Agrégat CLR – Nouveauté 2008

En ce moment, je teste pas mal SQL Server 2008 et en particulier les améliorations par rapport à la version précédente. Aujourd’hui, je me suis intéressé aux fonctionnalités de la SQLCLR et j’ai voulu savoir si une des limitations de 2005 était levée.

Le problème était le suivant (le fait que je parle à l’imparfait devrait vous aiguiller sur la réponse) : dans une fonction d’agrégat CLR, il n’était possible de fournir qu’un seul paramètre à la méthode Accumulate. Ceci était pénalisant pour certaines fonctions à double entrée ou pour paramétrer le comportement d’autre.

Par exemple, sur une fonction de concaténation (très utile dans les reports), il était impossible de préciser le caractère à utiliser comme séparateur. Cela a entraîné (chez nous en tout cas) de grands débats sur le choix caractère à utiliser dans le code .NET. Cela impliquait aussi l’utilisation de méthodes de Replace dans les couches supérieures pour traiter le caractère.

Venons-en à la solution que propose SQL Server 2008 maintenant.  Je suis en fait tombé sur la documentation suivante :

CREATE AGGREGATE [ schema_name . ] aggregate_name
        (@param_name <input_sqltype> 
        [ ,...n ] )

J’ai été intrigué et admiratif sur le ..n dans la liste de paramètres qui suppose que les fonctions d’agrégat de 2008 supportent le multi-paramètre.
Je me suis empressé de modifier quelque peu l’agrégat de concaténation des exemples de SQL Server et j’ai modifié la méthode Accumulate de cette façon :

[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(…)]
public struct Concat {
    […]
    public void Accumulate(SqlString Value, SqlString separator)
    {
        if (!isFirst)
            sb.Append(separator);
        else
            isFirst = false;
        sb.Append(Value.Value);
    }

Après avoir intégré l’Assembly dans ma base, je mappe la fonction d’agrégat :

CREATE AGGREGATE [dbo].[Concat] (
  @value [nvarchar](4000),
  @separator [nvarchar](10))
RETURNS[nvarchar](4000)
EXTERNAL NAME [BewiseUtils].[Bewise.SqlServer.Concat]

Et le test final :

SELECT dbo.Concat(LastName, ', ')
FROM Person.Person

Et voila le travail… Chacun peu choisir son séparateur dans la fonction de concaténation.

Laisser un commentaire