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

更新:2007 年 11 月

通过向 SQL Server 项目添加“聚合”项创建 SQL 聚合。部署成功后,在托管代码中创建的聚合像其他任何 SQL Server 聚合一样被调用和执行。

说明:

在默认情况下,Microsoft SQL Server 中关闭了公共语言运行时 (CLR) 集成功能。必须启用该功能才能使用 SQL Server 项目项。若要启用 CLR 集成,请使用 sp_configure 存储过程的 clr enabled 选项。有关更多信息,请参见启用 CLR 集成

说明:

SQL Server 集合要求实现四个特别方法:Init、Accumulate、Merge 和 Terminate。有关更多信息,请参见《SQL Books Online》(SQL 联机丛书)中的“SQL CLR .NET User-Defined Aggregate Functions”(SQL CLR .NET 用户定义的聚合函数)主题。

说明:

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

创建 SQL Server 聚合

创建 SQL Server 聚合

  1. 打开一个现有的“SQL Server 项目”,或者创建一个新项目。有关更多信息,请参见如何:创建 SQL Server 项目

  2. 从“项目”菜单中选择“添加新项”。

  3. “添加新项”对话框 中选择“聚合”。

  4. 输入新聚合的“名称”。

  5. 添加执行聚合时要运行的代码。请参见下面的第一个示例。

说明:

C++ 示例在编译时必须使用 /clr:safe 编译器选项。

  1. 将聚合部署到 SQL Server。有关更多信息,请参见如何:将 SQL Server 项目项部署到 SQL Server 中

  2. 通过在 SQL Server 上执行聚合对其进行调试。请参见下面的第二个示例。

示例

此示例创建对元音计数的聚合。此聚合对字符串数据类型的列中的元音计数。聚合包含以下四个必需的可运行多个线程的方法:Init、Accumulate、Merge 和 Terminate。

Imports System
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server

<Serializable()> _
<SqlUserDefinedAggregate(Format.Native)> _
Public Structure CountVowels

    ' count only the vowels in the passed-in strings
    Private countOfVowels As SqlInt32


    Public Sub Init()
        countOfVowels = 0
    End Sub


    Public Sub Accumulate(ByVal value As SqlString)
        Dim stringChar As String
        Dim indexChar As Int32

        ' for each character in the given parameter
        For indexChar = 0 To Len(value.ToString()) - 1

            stringChar = value.ToString().Substring(indexChar, 1)

            If stringChar.ToLower() Like "[aeiou]" Then

                ' it is a vowel, increment the count
                countOfVowels = countOfVowels + 1
            End If
        Next
    End Sub


    Public Sub Merge(ByVal value As CountVowels)

        Accumulate(value.Terminate())
    End Sub


    Public Function Terminate() As SqlString

        Return countOfVowels.ToString()
    End Function
End Structure
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

[Serializable]
[SqlUserDefinedAggregate(Format.Native)]
public struct CountVowels
{
    // count only the vowels in the passed-in strings
    private SqlInt32 countOfVowels;


    public void Init()
    {
        countOfVowels = 0;
    }


    public void Accumulate(SqlString value)
    {
        // list of vowels to look for
        string vowels = "aeiou";

        // for each character in the given parameter
        for (int i=0; i < value.ToString().Length; i++)
        {
            // for each character in the vowels string
            for (int j=0; j < vowels.Length; j++)
            {
                // convert parameter character to lowercase and compare to vowel
                if (value.Value.Substring(i,1).ToLower() == vowels.Substring(j,1))
                {
                    // it is a vowel, increment the count
                    countOfVowels+=1;
                }
            }
        }
    }


    public void Merge(CountVowels value)
    {
        Accumulate(value.Terminate());
    }


    public SqlString Terminate()
    {
        return countOfVowels.ToString();
    }
}
#include "stdafx.h"

#using <System.dll>
#using <System.Data.dll>
#using <System.Xml.dll>

using namespace System;
using namespace System::Data;
using namespace System::Data::Sql;
using namespace System::Data::SqlTypes;
using namespace Microsoft::SqlServer::Server;

// In order to debug your Aggregate, add the following to your debug.sql file:
//
// SELECT LastName, COUNT(LastName) AS CountOfLastName, dbo.CountVowels(LastName) AS CountOfVowels
// FROM Person.Contact
// GROUP BY LastName
// ORDER BY LastName
//

[Serializable]
[SqlUserDefinedAggregate(Format::Native)]
public value struct CountVowels
{
public:
    void Init()
    {
        countOfVowels = 0;
    }

    void Accumulate(SqlString value)
    {
        // list of vowels to look for
        String ^vowels = "aeiou";

        // for each character in the given parameter
        for (int i=0; i < value.ToString()->Length; i++)
        {
            // for each character in the vowels string
            for (int j=0; j < vowels->Length; j++)
            {
                // convert parameter character to lowercase and compare to vowel
                if (value.Value->Substring(i, 1)->ToLower() == vowels->Substring(j, 1))
                {
                    // it is a vowel, increment the count
                    countOfVowels+=1;
                    break;
                }
            }
        }
    }

    void Merge(CountVowels value)
    {
        Accumulate(value.Terminate());
    }

    SqlTypes::SqlString Terminate()
    {
        return countOfVowels.ToString();
    }

private:
    // count only the vowels in the passed-in strings
    SqlInt32 countOfVowels;
};

部署聚合后,在 SQL Server 上运行它以进行调试并验证是否返回正确的数据。此查询返回对 Contact 表中 LastNames 列的所有值的元音计数的结果集。

SELECT LastName, COUNT(LastName) AS CountOfLastName, dbo.CountVowels(LastName) AS CountOfVowels
FROM Person.Contact
GROUP BY LastName
ORDER BY LastName

请参见

任务

如何:创建 SQL Server 项目

如何:创建和运行 CLR SQL Server 存储过程

如何:创建和运行 CLR SQL Server 触发器

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

如何:创建和运行 CLR SQL Server 用户定义的函数

如何:创建和运行 CLR SQL Server 用户定义的类型

演练:使用托管代码创建存储过程

如何:调试 SQL CLR 存储过程

概念

SQL Server CLR 集成简介

使用托管代码创建数据库对象的好处

SQL Server 项目的项模板

参考

SQL Server 项目和数据库对象的属性

其他资源

SQL CLR 数据库调试