SQL CLR与Hash Group聚合

时间:2017-05-02 19:42:52

标签: c# sql .net sql-server clr

可以将CLR聚合与Hash Group提示一起使用吗?

我尝试了GROUP_CONCAT()聚合函数(您可以在codeplex http://groupconcat.codeplex.com/上找到它),但问题在于我尝试过的每个自定义聚合函数。

当我跑步时:

SELECT 
   Position,
   dbo.GROUP_CONCAT(Name)
FROM TestTable
GROUP BY Position
OPTION (HASH GROUP)

我总是得到错误:

  

消息8622,级别16,状态1,行1查询处理器由于此查询中定义的提示而无法生成查询计划。重新提交   查询时没有指定任何提示,也没有使用SET FORCEPLAN。

以下是我可以在http://groupconcat.codeplex.com/找到的用于创建程序集的测试表和代码:

CREATE TABLE [dbo].[TestTable](
    [Id] [int] NOT NULL,
    [Name] [varchar](50) NULL,
    [Position] [int] NULL
)

GO
INSERT [dbo].[TestTable] ([Id], [Name], [Position]) VALUES (1, N'dfgdfg', 1)
GO
INSERT [dbo].[TestTable] ([Id], [Name], [Position]) VALUES (2, N'dfdfg', 2)
GO
INSERT [dbo].[TestTable] ([Id], [Name], [Position]) VALUES (3, N'rgererg', 1)
GO

这是C#中的聚合函数定义:

 [Serializable]
    [SqlUserDefinedAggregate(Format.UserDefined,
                             MaxByteSize = -1,
                             IsInvariantToNulls = true,
                             IsInvariantToDuplicates = false,
                             IsInvariantToOrder = true,
                             IsNullIfEmpty = true)]
    public struct GROUP_CONCAT : IBinarySerialize
    {
        private Dictionary<string, int> values;

    public void Init()
    {
        this.values = new Dictionary<string, int>();
    }

    public void Accumulate([SqlFacet(MaxSize = 4000)] SqlString VALUE)
    {
        if (!VALUE.IsNull)
        {
            string key = VALUE.Value;
            if (this.values.ContainsKey(key))
            {
                this.values[key] += 1;
            }
            else
            {
                this.values.Add(key, 1);
            }
        }
    }

    public void Merge(GROUP_CONCAT Group)
    {
        foreach (KeyValuePair<string, int> item in Group.values)
        {
            string key = item.Key;
            if (this.values.ContainsKey(key))
            {
                this.values[key] += Group.values[key];
            }
            else
            {
                this.values.Add(key, Group.values[key]);
            }
        }
    }

    [return: SqlFacet(MaxSize = -1)]
    public SqlString Terminate()
    {
        if (this.values != null && this.values.Count > 0)
        {
            StringBuilder returnStringBuilder = new StringBuilder();

            foreach (KeyValuePair<string, int> item in this.values)
            {
                for (int value = 0; value < item.Value; value++)
                {
                    returnStringBuilder.Append(item.Key);
                    returnStringBuilder.Append(",");
                }
            }
            return returnStringBuilder.Remove(returnStringBuilder.Length - 1, 1).ToString();
        }

        return null;
    }

    public void Read(BinaryReader r)
    {
        int itemCount = r.ReadInt32();
        this.values = new Dictionary<string, int>(itemCount);
        for (int i = 0; i <= itemCount - 1; i++)
        {
            this.values.Add(r.ReadString(), r.ReadInt32());
        }
    }

    public void Write(BinaryWriter w)
    {
        w.Write(this.values.Count);
        foreach (KeyValuePair<string, int> s in this.values)
        {
            w.Write(s.Key);
            w.Write(s.Value);
        }
    }
}

0 个答案:

没有答案