消息 6558:CREATE AGGREGATE 失败,因为类型 'Concatenate' 不符合 UDAGG 规范

Msg 6558: CREATE AGGREGATE failed because type 'Concatenate' does not conform to UDAGG specification

我创建了一个 SQLCLR 程序集并添加了它,当我 运行 T-SQL 命令时:

CREATE AGGREGATE Concat (@input nvarchar(max))
RETURNS nvarchar(max)
EXTERNAL NAME Sql_ClrAggregates.Concatenate;

我收到错误:

Msg 6558, Level 16, State 1, Line 1
CREATE AGGREGATE failed because type 'Concatenate' does not conform to UDAGG specification due to method 'Accumulate'.

UDAGG 规格是什么?

UDAGG 规范部分引用了 CREATE AGGREGATEEXTERNAL NAME 之间提供的位,即

Concat (@input nvarchar(max)) RETURNS nvarchar(max)

检查这是否与程序集中的方法匹配,在 c# 中这将是

public void Accumulate(SqlString Value)
{ ... }

终止函数返回结果:

public SqlString Terminate()
{ ... }

如果您添加 public 不符合 requirements 的字段、方法等,您将得到类似的错误,但该字段将被特别提及。

我会说 UDAGG 规范 是文档 Requirements for CLR User-Defined Aggregates(链接到 2014 版)

它说明了您需要做什么。您的错误表明问题出在 Accumulate 方法上,因此我们检查要求:

input_type should be the managed SQL Server data type equivalent to the native SQL Server data type specified by input_sqltype in the CREATE AGGREGATE statement.

当然,您的回答包含了一些关于您出错地方的细节的更多细节,由于您没有展示问题中的C#代码。


正如您的回答所暗示的那样,"bit supplied between CREATE AGGREGATE and EXTERNAL" 没有正式名称。 CREATE AGGREGATE 的完整语法描述为:

CREATE AGGREGATE [ schema_name . ] aggregate_name 
        (@param_name <input_sqltype> 
        [ ,...n ] )
RETURNS <return_sqltype>
EXTERNAL NAME assembly_name [ .class_name ]

<input_sqltype> ::= 
        system_scalar_type | { [ udt_schema_name. ] udt_type_name }

<return_sqltype> ::= 
        system_scalar_type | { [ udt_schema_name. ] udt_type_name }

作为进一步的例子,这个聚合:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.Native)]
public struct SqlAggregate1
{
    public void Accumulate(SqlString Value)
    {
        // Put your code here
    }

    public void Merge (SqlAggregate1 Group)
    {
        // Put your code here
    }

    public SqlString Terminate ()
    {
        // Put your code here
        return new SqlString (string.Empty);
    }

    // This is a place-holder member field
    public int _var1;
}

有了这个SQL:

CREATE AGGREGATE [dbo].[SqlAggregate1](@Value NVARCHAR (MAX))
    RETURNS NVARCHAR (MAX)
    EXTERNAL NAME [Database2].[SqlAggregate1];

产生错误:

Msg 6558, Level 16, State 1, Line 1 CREATE AGGREGATE failed because type 'SqlAggregate1' does not conform to UDAGG specification due to method 'Init'.

尽管 AccumulateTerminate 以及 "the bit supplied between CREATE AGGREGATE and EXTERNAL NAME" 的定义完全一致。