如何:创建和运行 CLR SQL Server 聚合
通过向 SQL Server 项目添加“聚合”项创建 SQL 聚合。部署成功后,在托管代码中创建的聚合像其他任何 SQL Server 聚合一样被调用和执行。
注意; 在默认情况下,Microsoft SQL Server 中关闭了公共语言运行库 (CLR) 集成功能。必须启用该功能才能使用 SQL Server 项目项。若要启用 CLR 集成,请使用 sp_configure 存储过程的“启用 clr”选项。有关更多信息,请参见 启用 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 聚合打开一个现有的“SQL Server 项目”,或者创建一个新项目。有关更多信息,请参见 如何:创建 SQL Server 项目。
从“项目”菜单中选择“添加新项”。
在 “添加新项”对话框 中选择“聚合”。
输入新聚合的“名称”。
添加执行聚合时要运行的代码。请参见下面的第一个示例。
注意; C++ 示例在编译时必须使用 /clr:safe 编译器选项。
将聚合部署到 SQL Server。有关更多信息,请参见 如何:将 SQL Server 项目项部署到 SQL Server 中。
通过在 SQL Server 上执行聚合对其进行调试。请参见下面的第二个示例。
示例此示例创建对元音计数的聚合。此聚合对字符串数据类型的列中的元音计数。聚合包含以下四个必需的可运行多个线程的方法:Init、Accumulate、Merge 和 Terminate。
Visual Basic 复制代码Imports SystemImports System.Data.SqlTypesImports 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 FunctionEnd StructureC# 复制代码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(); }}C++ 复制代码#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 CountOfVowelsFROM Person.ContactGROUP BY LastNameORDER BY LastName