2009-03-07 9 views
3

J'ai lu here (et ailleurs) qu'il est possible, dans SQL Server 2008, de construire un agrégat défini par l'utilisateur qui peut renvoyer une chaîne de plus de 8000 caractères. C'est exactement ce dont j'ai besoin. Supposément, la méthode consiste à mettre maxByteSize à -1 au lieu d'un nombre btw 1 et 8000; ceci devrait permettre n'importe quelle taille jusqu'à 2GB. Pour une raison quelconque, apparemment, vous ne pouvez pas déployer directement à partir de Visual Studio 2008 si vous utilisez ce paramètre; donc vous devez déployer manuellement. Donc: Je construis mon projet - GroupConcat (qui est supposé simuler l'agrégateur group_concat de MySQL) - ce qui me donne, dans le dossier bin du projet, un fichier "SqlClassLibrary.dll". Conformément aux instructions de la page ci-dessus liée, je crée l'assembly dans SQL Server. La commande s'exécute avec succès. Cependant, lorsque je tente de réellement utiliser l'agrégateur de groupconcat:Agrégat défini par l'utilisateur dans SQL Server 2008 - Comment déployer avec MaxByteSize = -1?

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

... il dit qu'il ne peut pas être trouvé. Tout fonctionne correctement si je mets maxByteSize à 8000 et que je les déploie directement à partir de VS2008, mais j'ai besoin de> 8000. Quelqu'un sait ce que je fais mal?

Merci -Dan

REMARQUE: je besoin spécifiquement d'avoir une fonction d'agrégation de groupconcat plutôt que d'utiliser quelques-unes des astuces SQL Server J'ai souvent vu.

Répondre

1

figured it out ... Après la construction de la solution Vis studio, en supposant que je l'ai laissé tomber .dll il crée dans c: \ temp et l'a appelé 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 

qui le fait .

3

Alternativement, vous pouvez utiliser la propriété MaxSize de SqlFacetAttribute pour indiquer la taille de la variable. Notez que dans l'exemple ci-dessous, j'ai appliqué cet attribut aux paramètres SqlString de la méthode et à la valeur de retour de la méthode Terminate. Il en résulte la signature SQL suivante:

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); 
} 

Je ne sais pas si cela est plus « correcte » que ce que vous avez fini par faire, mais il semble plus naturel.

+0

Très utile à connaître. +1 Merci! – DanM