Agrégat défini par l'utilisateur dans SQL Server 2008 - Comment déployer avec MaxByteSize = -1?
-
05-07-2019 - |
Question
Je lis ici (et ailleurs) qu'il est possible, dans SQL Server 2008, de créer un agrégat défini par l'utilisateur pouvant renvoyer une chaîne de plus de 8 000 caractères. C'est exactement ce dont j'ai besoin.
Soi-disant, la méthode consiste à définir maxByteSize sur -1 au lieu d’un nombre compris entre 1 et 8000; cela devrait permettre n'importe quelle taille jusqu'à 2 Go.
Pour une raison quelconque, apparemment, vous ne pouvez pas déployer directement depuis Visual Studio 2008 si vous utilisez ce paramètre; vous devez donc 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 liée ci-dessus, je construis l'assembly dans SQL Server. La commande s'exécute avec succès. Cependant, lorsque j'essaie réellement d'utiliser l'agrégateur de groupconcat:
sélectionnez un département, dbo.groupconcat (projectNumber) à partir du groupe de projets en tête par département
... il est dit qu'on ne peut pas le trouver. Tout cela fonctionne correctement si je règle maxByteSize sur 8000 et le déploie directement à partir de VS2008, mais j'ai besoin de > 8000. Quelqu'un sait ce que je fais mal?
Merci -dan
REMARQUE: il me faut spécifiquement une fonction d'agrégation de groupconcat plutôt que d'utiliser certaines astuces de SQL Server que j'ai souvent vues.
La solution 2
Je l'ai compris ... Après avoir créé la solution dans Vis Studio, en supposant que j'ai supprimé le fichier .dll créé dans c: \ temp et appelé cela 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
Cela le fait.
Autres conseils
Vous pouvez également utiliser la propriété MaxSize
de SqlFacetAttribute
pour indiquer la taille de varchar. Notez que dans l'exemple ci-dessous, j'ai appliqué cet attribut aux paramètres SqlString
de la méthode Accumulate
et à la valeur de retour de la méthode Terminate
. Cela se traduit par la signature SQL suivante:
AGGREGATE [dbo]. [Concaténer] (@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 s'il s'agit d'un message "correct". que ce que vous avez fini par faire, mais cela semble plus naturel.