是否可以使用CLR聚合与哈希组提示?
我尝试了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查询处理器无法生成查询计划,因为此查询中定义了提示。在不指定任何提示和不使用SETFORCEPLAN的情况下重新提交查询。
下面是我的测试表和代码,你可以在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);
}
}
}
1条答案
按热度按时间fhg3lkii1#
对于任何试图访问http://groupconcat.codeplex.com/(失败)的人,您可以运行以下脚本。我在我的实时服务器上有这个程序集,不得不得到一个新的开发机器。页面不存在页面不存在
我从我的服务器上生成了这个,并在我的开发机器上运行,它工作正常
我知道这种格式看起来很危险,但它很安全
我的实时服务器:
. and my dev machine after executing:
USE [master] GO
就像我说的,我知道你不能从上面的代码中看到它的作用,所以要小心。当我最初使用来自codeplex的脚本安装它时,它是以大约五个“CREATE FUNCTION”脚本的形式出现的,其中一个是GROUP_CONCAT。我在SELECT语句中使用它,如下所示
dbo.GROUP_CONCAT(bmt.BonusCode)
,它连接BonusCode
字符串值。我相信这是必要的,因为我的版本的SQL服务器是一些落后于最新的,并没有原生提供这一点
我还必须首先执行以下操作