Tutorial: Depurar un agregado definido por el usuario de SQL CLR

Actualización: noviembre 2007

Este tema se aplica a:

Edición

Visual Basic

C#

C++

Web Developer

Express

Standard

Pro y Team

Leyenda de la tabla:

Se aplica

No procede

Comando o comandos ocultos de forma predeterminada.

Este ejemplo muestra cómo depurar un agregado definido por el usuario de SQL CLR. En este ejemplo se crea en la base de datos de ejemplo AdventureWorks una nueva función de agregado de SQL CLR denominada Concatenate. Cuando esta función se invoca en una instrucción SQL, concatenará todos los valores de la columna especificada como parámetro de entrada.

Nota:

Los cuadros de diálogo y comandos de menú que se ven pueden diferir de los descritos en la Ayuda, en función de los valores de configuración o de edición activos. Para cambiar la configuración, elija la opción Importar y exportar configuraciones del menú Herramientas. Para obtener más información, vea Valores de configuración de Visual Studio.

Para depurar una función de agregado de SQL CLR

  1. En un nuevo proyecto de SQL Server, establezca una conexión a la base de datos de ejemplo AdventureWorks. Para obtener más información, vea Cómo: Conectarse a una base de datos.

  2. Cree una nueva función utilizando el código de la primera de las secciones de ejemplo siguientes y asígnele el nombre Concatenate.cs. Para obtener más información, vea Cómo: Desarrollar con el tipo de proyecto de SQL Server.

  3. Agregue un script que pruebe la función incluyéndola en una instrucción SELECT. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el directorio SecuenciasDePrueba, seleccione Agregar script de prueba e inserte el código de la segunda parte del ejemplo de este tutorial. Guarde el archivo con el nombre Concatenate.sql. Haga clic con el botón secundario del mouse en el nombre del archivo y, a continuación, elija Establecer como script de depuración predeterminado.

  4. Coloque un punto de interrupción en Concatenate.csdentro del método Accumulate en la instrucción if. Para ello, haga clic en el margen izquierdo sombreado de la ventana Editor de texto y, en el menú Depurar, haga clic en Iniciar para compilar, implementar y ejecutar una prueba unitaria del proyecto. Si el puntero de instrucción, designado por una flecha amarilla, aparece sobre un punto de interrupción, está depurando la función.

  5. Pruebe diferentes características de depuración.

    1. El método Accumulate se ejecuta una vez por cada una de las filas que conforman la cláusula GROUP BY del script de Concatenate.sql. Si hace clic varias veces en Paso a paso por instrucciones en el menú Depurar, podrá observar cómo se genera el resultado del método.

    2. En la ventana Variables locales, abra la variable value que contiene el nombre del almacén actualmente en proceso.

    3. Haga clic en la variable this. El nodo secundario intermediateResult se devolverá desde esta función y contendrá todos los nombres de almacén hasta el actual concatenados y separados por comas.

    4. En el editor de texto, haga doble clic en la variable intermediateResult para seleccionarla. Arrastre intermediateResult hasta un punto cualquiera de la ventana Inspección. La variable se agrega ahora a la lista de variables inspeccionadas.

    5. Recorra el método varias veces. El valor de intermediateResult irá cambiando a lo largo del método, con un nombre de almacén adicional concatenado al final.

    6. Haga clic en el punto de interrupción para quitarlo y agregue un punto de interrupción a la primera instrucción dentro del método Terminate. Este método devuelve el resultado al llamador. Para recorrer paso a paso las instrucciones, en el menú Depurar, haga clic en Iniciar. A continuación, puede recorrerlo haciendo clic en Paso a paso por instrucciones en el Depurar. Deténgase cuando llegue a la instrucción return.

    7. Haga clic de nuevo en Continuar para finalizar la depuración de la función.

Ejemplo

Éste es el código de la función de agregado que se utiliza en este ejemplo.

using System;
using System.Data.Sql;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.IO;
using System.Text;
[Serializable]
[SqlUserDefinedAggregate( 
    //use CLR serialization to serialize the intermediate result. 
    Format.UserDefined, 
    //Optimizer property: 
    IsInvariantToNulls=true,
    //Optimizer property: 
    IsInvariantToDuplicates=false,
    //Optimizer property: 
    IsInvariantToOrder=false,
    //Maximum size in bytes of persisted value: 
    MaxByteSize=8000)
] 
public class Concatenate: IBinarySerialize 
{ 
    /// <summary> 
    /// Variable holds intermediate result of the concatenation 
    /// </summary> 
    private StringBuilder intermediateResult; 
    /// <summary> 
    /// Initialize the internal data structures 
    /// </summary> 
    public void Init( ) 
    { 
        intermediateResult = new StringBuilder(); 
    } 
    /// <summary> 
    /// Accumulate the next value, nop if the value is null 
    /// </summary> 
    /// <param name="value"></param> 
    public void Accumulate(SqlString value) 
    { 
        if(value.IsNull) 
        { 
            return; 
        } 
        intermediateResult.Append(value.Value).Append(','); 
    } 
    /// <summary> 
    /// Merge the partially computed aggregate with this aggregate. 
    /// </summary> 
    /// <param name="other"></param> 
    public void Merge( Concatenate other) 
    { 
        intermediateResult.Append(other.intermediateResult); 
    } 
    /// <summary> 
    /// Called at end of aggregation, to return results. 
    /// </summary> 
    /// <returns></returns> 
    public SqlString Terminate() 
    { 
        string output = string.Empty; 
        //Delete the trailing comma, if any .
        if (intermediateResult != null && intermediateResult.Length > 0) 
            output = intermediateResult.ToString(0, intermediateResult.Length-1); 
        return new SqlString(output); 
    } 
    public void Read(BinaryReader r) 
    { 
        intermediateResult = new StringBuilder(r.ReadString()); 
    } 
    public void Write(BinaryWriter w) 
    { 
        w.Write(intermediateResult.ToString()); 
    } 
}

Este es el script de prueba que llama a la función.

SELECT scu.SalesPersonID, dbo.Concatenate(sst.Name)
FROM Sales.Customer as scu 
INNER JOIN Sales.Store as sst
    ON scu.CustomerID    = sst.CustomerID
INNER JOIN Sales.SalesPerson as spr
    ON scu.SalesPersonID = spr.SalesPersonID
WHERE    scu.SalesPersonID = 283
GROUP BY scu.SalesPersonID

Vea también

Tareas

Cómo: Crear y ejecutar un agregado CLR de SQL Server

Otros recursos

Depuración de bases de datos de SQL CLR