zoukankan      html  css  js  c++  java
  • 创建聚合函数

    说明:本文依据网络转载整理而成,因为时间关系,其中原理暂时并未深入研究,只是整理备份留个记录而已。

    目标:在SQL Server中自定义聚合函数,在Group BY语句中 ,不是单纯的SUM和MAX等运算,可以加入拼接字符串。

    环境:

        1:Sqlserver 2008 R2  

        2:Visual Studio 2013 

    第一部分:

    .net代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    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支持的配置

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

    第三步:加载CLR程序集并创建自定义函数

    1
    2
    3
    4
    5
    USE Test   --选择数据库
    CREATE ASSEMBLY SQL_Aggregate FROM 'E:WorkSpaceLetMeTryWindowsFormsApplication2SqlCustomFunctioninDebugSqlCustomFunction.dll'       --生成的DLL路径
    GO
    CREATE AGGREGATE SQL_Aggregate (@input nvarchar(200),@contChar nvarchar(1)) RETURNS nvarchar(max)
    EXTERNAL NAME SQL_Aggregate.Concatenate

    生成的时候如果提示:针对带有 SAFE 或 EXTERNAL_ACCESS 选项的程序集“XXX”的 CREATE 或 ALTER ASSEMBLY 失败

    采用 sp_add_trusted_assembly的方式添加信任到数据库里去.
    
    DECLARE @hash AS BINARY(64) = (SELECT HASHBYTES('SHA2_512', (SELECT * FROM OPENROWSET (BULK 'c:wwwwXXX.dll', SINGLE_BLOB) AS [Data])))
    
    EXEC sp_add_trusted_assembly @hash

     
     

    第四步:测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    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
  • 相关阅读:
    VANET
    OTCL,面向对象的脚本一
    NetFPGA-SUME下reference_nic测试
    Mininet-wifi安装和简单使用
    18寒假
    DistBlockNet:A Distributed Blockchains-Based Secure SDN Architecture for IOT Network
    SDVN
    Papers3
    高级软件工程实践总结
    Beta集合
  • 原文地址:https://www.cnblogs.com/jyzjh/p/13599402.html
Copyright © 2011-2022 走看看