Pergunta

Eu li aqui (e outros) que é possível, no SQL Server 2008, para construir um agregado definido pelo usuário, que pode retornar uma seqüência de mais de 8000 caracteres. Este é exatamente o que eu preciso.

Supostamente, o método é para definir MaxByteSize a-1 em vez de um número aliás 1 e 8000; isto deve permitir qualquer tamanho até 2GB.

Por alguma razão, aparentemente, você não pode implantar direto do Visual Studio 2008 se você usar essa configuração; então você precisa para implantar manualmente.

Assim: eu construir meu projeto - GroupConcat (que é suposto para simular agregador group_concat do MySQL) - o que me dá, na pasta bin do projeto, um arquivo "SqlClassLibrary.dll". Acordo com as instruções na página acima ligado, eu construir o conjunto em SQL Server. O comando é executado com êxito. No entanto, quando tento realmente uso o agregador groupconcat:

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

... ele diz que não pode ser encontrado. Esta tudo bem funciona se eu definir MaxByteSize a 8000 e implantar diretamente de dentro VS2008, mas eu preciso> 8000. Alguém sabe o que estou fazendo de errado?

Graças -dan

NOTA:. Eu especificamente precisa ter uma função groupconcat agregador em vez de usar alguns dos truques do SQL Server Eu sempre vi

Foi útil?

Solução 2

Descobri-lo ... Depois de construir a solução em Vis Studio, supondo que eu deixei cair o arquivo .dll que ele cria em c: \ temp e chamou-lhe 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

Isso faz.

Outras dicas

Como alternativa, você pode usar a propriedade MaxSize de SqlFacetAttribute para indicar o tamanho varchar. Note-se que no exemplo a seguir que este atributo aplicado com os parâmetros SqlString no método Accumulate e para o valor de retorno do método Terminate. Isto resulta na seguinte assinatura de 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);
}

Eu não sei se este é mais "correta" do que o que você acabou fazendo, mas parece mais natural.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top