Сообщение 6558: сбой CREATE AGGREGATE, так как тип 'Concatenate' не соответствует спецификации UDAGG

Я создал сборку SQLCLR и добавил ее, когда запускаю команду T-SQL:

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

Я получаю ошибку:

Сообщение 6558, уровень 16, состояние 1, строка 1
CREATE AGGREGATE не удалось, так как тип 'Concatenate' не соответствует спецификации UDAGG из-за метода 'Accumulate'.

Что такое спецификация UDAGG?

2 ответа

Решение

Спецификация UDAGG частично относится к биту, поставляемому между CREATE AGGREGATE а также EXTERNAL NAME т.е.

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

Убедитесь, что это соответствует методу в сборке, в C# это будет

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

с функцией завершения, возвращающей результат:

public SqlString Terminate()
{ ... }

Вы получите аналогичную ошибку, если добавите открытые поля, методы и т. Д., Которые не соответствуют требованиям, но это поле будет упомянуто конкретно.

Я бы сказал, что Спецификация UDAGG - это документ Требования к пользовательским агрегатам CLR (связано с версией 2014)

В нем говорится,что вы должны сделать. Ваша ошибка утверждает, что проблема сAccumulateМетод, и поэтому мы проверяем требования:

input_type должен быть управляемым типом данных SQL Server, эквивалентным собственному типу данных SQL Server, указанному вinput_sqltype в оператореCREATE AGGREGATE.

Конечно, ваш ответ содержит немного больше подробностей о том, где вы ошиблись, но я не смог это прокомментировать, поскольку вы не указали код C# в вопросе.


Не существует формального имени, присвоенного биту CREATE AGGREGATEа также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];

Выдает ошибку:

Сообщение 6558, Уровень 16, Состояние 1, Строка 1, СОЗДАТЬ АГРЕГАТ не удалось, так как тип 'SqlAggregate1' не соответствует спецификации UDAGG из-за метода 'Init'.

Несмотря на абсолютное согласие между определениями Accumulate а также Terminate и "бит подается между CREATE AGGREGATE а также EXTERNAL NAME".

Другие вопросы по тегам