SQL Server中的聚合,常用的比如max,count之類。 我們現在也可以在SQLCLR裡創建自定義的聚合。Visual Studio 2005中提供的聚合模板是一個結構,標注了[Serializable],[SqlUserDefinedAggregate]標簽,這將讓SQLCLR知道這是一個聚合函數。
看一段代碼,這段代碼來自SQL Server 2005聯機叢書,本來自己想寫一段,但突然公司有些事要做,沒時間了。示例代碼作用是合並同一部書(ID相同)的作者。
using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
using System.Text;
[Serializable]
[SqlUserDefinedAggregate(
Format.UserDefined, //use clr serialization to serialize the intermediate result
IsInvariantToNulls = true, //optimizer property
IsInvariantToDuplicates = false, //optimizer property
IsInvariantToOrder = false, //optimizer property
MaxByteSize = 8000) //maximum size in bytes of persisted value
]
public class Concatenate : IBinarySerialize
{
/**//// <summary>
/// The variable that holds the intermediate result of the concatenation
/// </summary>
private StringBuilder intermediateResult;
/**//// <summary>
/// Initialize the internal data structures
/// </summary>
public void Init()
{
this.intermediateResult = new StringBuilder();
}
/**//// <summary>
/// Accumulate the next value, not if the value is null
/// </summary>
/// <param name="value"></param>
public void Accumulate(SqlString value)
{
if (value.IsNull)
{
return;
}
this.intermediateResult.Append(value.Value).Append(',');
}
/**//// <summary>
/// Merge the partially computed aggregate with this aggregate.
/// </summary>
/// <param name="other"></param>
public void Merge(Concatenate other)
{
this.intermediateResult.Append(other.intermediateResult);
}
/**//// <summary>
/// Called at the end of aggregation, to return the results of the aggregation.
/// </summary>
/// <returns></returns>
public SqlString Terminate()
{
string output = string.Empty;
//delete the trailing comma, if any
if (this.intermediateResult != null
&& this.intermediateResult.Length > 0)
{
output = this.intermediateResult.ToString(0, this.intermediateResult.Length - 1);
}
return new SqlString(output);
}
public void Read(BinaryReader r)
{
intermediateResult = new StringBuilder(r.ReadString());
}
public void Write(BinaryWriter w)
{
w.Write(this.intermediateResult.ToString());
}
}
這裡有幾個比較重要的方法:Terminate,這個方法是聚合最後調用的方法,它返回最後的值。可以是SQL Server的任何標量。;Accumulate,聚合每處理一行數據的時候都會調用一次,並將要處理的數據傳給方法。可以在函數內部進行比如比較,合並之類的處理。;
CREATE TABLE BookAuthors
(
BookID int NOT NULL,
AuthorName nvarchar(200) NOT NULL
)
INSERT BookAuthors VALUES(1, 'Johnson')
INSERT BookAuthors VALUES(2, 'Taylor')
INSERT BookAuthors VALUES(3, 'Steven')
INSERT BookAuthors VALUES(2, 'Mayler')
INSERT BookAuthors VALUES(3, 'Roberts')
INSERT BookAuthors VALUES(3, 'Michaels')
SELECT BookID, dbo.MyAgg(AuthorName)
FROM BookAuthors
GROUP BY BookID
結果如下
BookID Author Names
1 Johnson
2 Taylor, Mayler
3 Roberts, Michaels, Steven
Microsoft SQL Server Management Studio為我們提供了數據庫內對象的集中管理功能,前面幾篇創建的SQLCLR對象,都可以在數據庫的可編程性下相應模塊裡找到。
這一系列到此就算是結束了,謝謝大家。