3

我在这里(和其他地方)读到,在 SQL Server 2008 中,可以构建一个用户定义的聚合,它可以返回一个超过 8000 个字符的字符串。这正是我所需要的。

据说,方法是将 maxByteSize 设置为 -1 而不是数字 btw 1 和 8000;这应该允许最大为 2GB 的任何大小。

显然,出于某种原因,如果使用此设置,则无法直接从 Visual Studio 2008 进行部署;所以你需要手动部署。

所以:我构建了我的项目——GroupConcat(它应该模拟 MySQL 的 group_concat 聚合器)——它在项目的 bin 文件夹中为我提供了一个文件“SqlClassLibrary.dll”。根据上述链接页面上的说明,我在 SQL Server 中构建程序集。命令执行成功。但是,当我尝试实际使用groupconcat 聚合器时:

select department, dbo.groupconcat(projectNumber) from projectleads group by department

...它说它找不到。如果我将 maxByteSize 设置为 8000 并直接从 VS2008 中部署,这一切都可以正常工作,但我需要 >8000。有人知道我在做什么错吗?

谢谢-丹

注意: 我确实需要一个 groupconcat 聚合函数,而不是使用一些我经常看到的 SQL Server 技巧。

4

2 回答 2

3

或者,您可以使用MaxSize属性SqlFacetAttribute来指示 varchar 大小。请注意,在下面的示例中,我将此属性应用于方法中的SqlString参数和Accumulate方法的返回值Terminate。这会产生以下 SQL 签名:

AGGREGATE [dbo].[Concatenate] (@value nvarchar(max), @order int, @seperator nvarchar(max)) RETURNS nvarchar(max)

[Serializable]
[SqlUserDefinedAggregate(
    Format.UserDefined,
    IsInvariantToOrder      = true,
    IsInvariantToNulls      = true,
    IsInvariantToDuplicates = false,
    IsNullIfEmpty           = false,
    MaxByteSize             = -1)]
public struct Concatenate : IBinarySerialize
{
    public void Init();

    public void Accumulate([SqlFacet(MaxSize = -1)] SqlString value,
                                                    SqlInt32  order,
                           [SqlFacet(MaxSize = -1)] SqlString seperator);

    public void Merge(Concatenate group);

    [return: SqlFacet(MaxSize = -1)]
    public SqlString Terminate();

    public void Read(BinaryReader r);

    public void Write(BinaryWriter w);
}

我不知道这是否比你最终做的更“正确”,但它似乎更自然。

于 2012-05-03T16:28:18.733 回答
1

想通了...在 Vis Studio 中构建解决方案后,假设我已将它创建的 .dll 放入 c:\temp 并将其命名为 GroupConcat.dll:

CREATE ASSEMBLY GroupConcat from 'C:\temp\GroupConcat.dll' with permission_set = safe
GO

CREATE AGGREGATE groupconcat(@input nvarchar(max))
RETURNS nvarchar(max)
EXTERNAL NAME GroupConcat
GO

这样做。

于 2009-03-10T12:43:53.393 回答