SQL Server 自定義聚合函數


說明:本文依據網絡轉載整理而成,因為時間關系,其中原理暫時並未深入研究,只是整理備份留個記錄而已。

 

目標:在SQL Server中自定義聚合函數,在Group BY語句中 ,不是單純的SUM和MAX等運算,可以加入拼接字符串。

 

環境:

    1:Sqlserver 2008 R2  

    2:Visual Studio 2013 

 

第一部分:

.net代碼:

using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
using System.Text;

[Serializable]
[SqlUserDefinedAggregate(
    Format.UserDefined,                 //使用UserDefined 序列化格式
    IsInvariantToNulls = true,          //聚合是否與空值有關
    IsInvariantToDuplicates = false,    //聚合是否與重復值有關
    IsInvariantToOrder = false,         //聚合是否與順序有關
    MaxByteSize = 8000)                 //聚合實例的最大大小(以字節為單位)
]
public class Concatenate : IBinarySerialize
{
    /// <summary>
    /// 定義變量
    /// </summary>
    private StringBuilder intermediateResult;
    /// <summary>
    /// 初始化
    /// </summary>
    public void Init()
    {
        this.intermediateResult = new StringBuilder();
    }

    /// <summary>
    /// 如果某一個字符不為空,用";"追加
    /// </summary>
    /// <param name="value"></param>
    public void Accumulate(SqlString value,string contChar) //symbol
    {
        if (value.IsNull)
        {
            return;
        }
        this.intermediateResult.Append(value.Value).Append(contChar);
    }
    /// <summary>
    /// 合並字符
    /// </summary>
    /// <param name="other"></param>
    public void Merge(Concatenate other)
    {
        this.intermediateResult.Append(other.intermediateResult);
    }

    /// <summary>
    /// 處理最后的","
    /// </summary>
    /// <returns></returns>
    public SqlString Terminate()
    {
        string output = string.Empty;
        //刪除最后的","
        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());
    }
}

 

編譯生成DLL,注意:SqlServer 2008 R2  不支持.Net Framework 4.5 ,所以生成dll的時候選在.net framework 3.5

 

第二步:啟用數據庫對CLR支持的配置

EXEC sp_configure 'clr enabled', 1
RECONFIGURE WITH OVERRIDE
GO

第三步:加載CLR程序集並創建自定義函數

USE Test   --選擇數據庫
CREATE ASSEMBLY SQL_Aggregate FROM 'E:\WorkSpace\LetMeTry\WindowsFormsApplication2\SqlCustomFunction\bin\Debug\SqlCustomFunction.dll'       --生成的DLL路徑
GO
CREATE AGGREGATE SQL_Aggregate (@input nvarchar(200),@contChar nvarchar(1)) RETURNS nvarchar(max)
EXTERNAL NAME SQL_Aggregate.Concatenate 

第四步:測試

USE Test

--創建測試數據
create table tb(ID int,Name varchar(10))
insert into tb 
select 1,'a'
union all select 1,'b'
union all select 2,'c'
union all select 2,'e'
union all select 3,'d'
go

--自定義聚合函數使用例子(第二個參數為拼接字符串的連接符)
select id,dbo.SQL_Aggregate([Name],'+') AS Test
from tb
group by id

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM