C#写的SQL聚合函数

 

2009/7/19
SQL Server 字符串连接聚合函数.
  1. 注册程序集:
    拷贝“SqlStrConcate.dll”至<sql安装根目录>/MSSQL.1/MSSQL/Binn目录下,执行下面的SQL:
    CREATE ASSEMBLY [SqlStrConcate]
    AUTHORIZATION [dbo]
    FROM 'D:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Binn/SqlStrConcate.dll'
    WITH PERMISSION_SET = SAFE
    GO
    上面的代码中, <sql安装根目录>为D:/Program Files/Microsoft SQL Server/
  2. 创建自定义函数:
    CREATE AGGREGATE StrConcate (@input nvarchar(200)) RETURNS nvarchar(max)
    EXTERNAL NAME SqlStrConcate.Concatenate
  3. 打开SQL Server 的CLR集成.方法:
    SQL Server 外围应用配置器 -> 功能的外围应用配置器 -> MSSQLSERVER -> Database Engine -> CLR集成 。勾选启用CLR集成
  4. OK了,现在你可以使用用户自定义字符串聚合函数StrConcate.测试代码如下:
  5. --------------------------------------------------------------
    -- 创建测试表
    --------------------------------------------------------------
    create table test_tb(pk_val  int, startdate varchar(10), enddate VARCHAR(10), corpname VARCHAR(20))
    
    --------------------------------------------------------------
    -- 插入测试数据
    --------------------------------------------------------------
    insert into test_tb     
    select 1, '2005-01-01', '2007-06-29', '方正科技'
    union all
    select 1, '2007-07-01', '2009-06-29', '清华紫光' 
    union all
    select 1, '2009-01-01', null, '用友软件'
    union all
    select 2, '1995-01-01', '2003-06-29', '微软中国'
    union all
    select 2, '2004-07-01', '2009-06-29', '盛大网络'  
    go
    
    --------------------------------------------------------------
    -- 查询测试
    --------------------------------------------------------------
    select pk_val, dbo.StrConcate(startdate + '~' + isnull(enddate, '至今') + ':' + corpname) lvl_str from test_tb group by pk_val
     
    --------------------------------------------------------------
    -- 查询结果
    --------------------------------------------------------------
    pk_val      lvl_str
    ----------- -----------------------------------------------------------------------------------------
    1           2005-01-01~2007-06-29:方正科技,2007-07-01~2009-06-29:清华紫光,2009-01-01~至今:用友软件
    2           1995-01-01~2003-06-29:微软中国,2004-07-01~2009-06-29:盛大网络
    
  6. SqlStrConcate.dll 代码(来自Sql Server的联机帮助)如下:
  7. 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());
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值