Aggregate no SQL Server 2008 definida pelo usuário - Como implantar com MaxByteSize = -1?
-
05-07-2019 - |
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
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.