演练:调试 SQL CLR 用户定义的聚合

更新:2007 年 11 月

本主题适用于:

版本

Visual Basic

C#

C++

Web Developer

速成版

主题不适用 主题不适用 主题不适用 主题不适用

标准版

主题不适用 主题不适用 主题不适用 主题不适用

专业团队版

主题适用 主题适用 主题适用 主题适用

表格图例:

主题适用

适用

主题不适用

不适用

主题适用,但命令默认情况下隐藏

默认情况下隐藏的一条或多条命令。

此示例显示如何调试 CLR SQL 用户定义的聚合。它在“AdventureWorks”示例数据库中创建一个新的名为“Concatenate”的 CLR SQL 聚合函数。当在 SQL 语句中调用此函数时,它将作为其输入参数的指定的列的所有值串联在一起。

说明:

显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您的当前设置或版本。若要更改设置,请在“工具”菜单上选择“导入和导出设置”。有关更多信息,请参见 Visual Studio 设置

调试 CLR SQL 聚合函数

  1. 在一个新的 SQL Server 项目中,建立一个到“AdventureWorks”示例数据库的连接。有关更多信息,请参见 如何:连接到数据库

  2. 使用以下示例部分中第一个示例的代码创建一个新的函数,并将其命名为“Concatenate.cs”。有关更多信息,请参见 如何:使用 SQL Server 项目类型进行开发

  3. 添加一个对该功能进行测试的脚本,方法是,在 SELECT 语句中包括该脚本。在“解决方案资源管理器”中右击“TestScripts”目录,选择“添加测试脚本”,然后插入本演练中第二个示例部分的代码。以“Concatenate.sql”名称保存文件。右击该文件名,然后单击“设置为默认调试脚本”。

  4. 将断点放置在 Concatenate.cs 中的 Accumulate 方法内的 if 语句上。若要执行此操作,请单击“文本编辑器”窗口左侧的灰色空白处,然后在“调试”菜单上单击“启动”,以对项目执行编译、部署和单元测试。以黄色箭头表示的指令指针出现在断点上时,说明正在调试函数。

  5. 尝试各种调试功能。

    1. 对于 Concatenate.sql 中构成脚本的 GROUP BY 子句的每一行,都会执行一次 Accumulate 方法。通过在“调试”菜单上重复单击“逐语句”,可监视方法结果的生成方式。

    2. 在“局部变量”窗口中,打开变量 value,它包含当前正处理的存储区名称。

    3. 单击变量 this。此函数将返回子节点 intermediateResult,该节点包含到当前存储名为止的所有存储名,这些存储名连接在一起并以逗号分隔。

    4. 在文本编辑器中,双击 intermediateResult 变量以选择它。将 intermediateResult 拖动到“监视”窗口,并将它放在窗口中的任意位置。该变量随即添加到受监视的变量列表中。

    5. 逐句通过方法几次。每次通过该方法时,intermediateResult 的值都将更改,并在结尾处连接另外一个存储名。

    6. 单击断点以将其移除,然后向 Terminate 方法内的第一个语句添加断点。此方法将结果返回给调用方。若要单步执行它,请在“调试”菜单上单击“启动”。现在可以通过单击“调试”菜单上的“单步执行”来逐句通过它。在遇到 return 语句时停止。

    7. 再次单击“继续”完成函数调试。

示例

下面是本示例中使用的聚合函数的代码。

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()); 
    } 
}

这是调用此函数的测试脚本。

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

请参见

任务

如何:创建和运行 CLR SQL Server 聚合

其他资源

SQL CLR 数据库调试