Comment mettre à jour un assembly CLR sans supprimer l'assembly de SQL Server

18

Comment puis-je mettre à jour une dll d'assembly de fonction (ou procédure) CLR sans avoir à supprimer et recréer l'assembly dans SQL Server (2008 R2)?

Dans l'état actuel des choses si je mets à jour un assembly (par exemple pour ajouter une nouvelle fonction), SQL Server n'honorera pas la DLL mise à jour tant que je n'aurai pas déposé l'assembly:

DROP ASSEMBLY CLRFunctions

Msg 6590, Level 16, State 1, Line 1
DROP ASSEMBLY failed because 'CLRFunctions' is referenced by object 'NormalizeString'.

Mais avant de pouvoir supprimer l'assembly, je dois d'abord supprimer toutes les fonctions qui y font référence:

DROP FUNCTION NormalizeString
DROP FUNCTION RemoveDiacritics
DROP FUNCTION RemoveCombiningDiacritics
DROP FUNCTION CombineLigatures
....
DROP FUNCTION PseudolocalizeArabic

Et puis je peux déposer l'assemblage:

DROP ASSEMBLY CLRFunctions

Maintenant je dois " créer " l'assemblage:

CREATE ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';

Et maintenant, je dois rechercher la déclaration de tous les UDF qui ont été enregistrés avant de les supprimer.

je préfère mettre à jour un assemblage et demander à SQL Server de commencer à l'utiliser.


Mise à jour : j'ai essayé DBCC FREEPROCCACHEau hasard de forcer une "recompilation", mais SQL Server utilise toujours l'ancien code.

Mise à jour : j'ai supprimé la DLL d'assembly CLRFunctions.dllet SQL Server est toujours en mesure d'exécuter le code (sans code qui devrait être impossible).

Ian Boyd
la source

Réponses:

16

Je pense que vous cherchez alter assembly. De BOL:

Si la clause FROM est spécifiée, ALTER ASSEMBLY met à jour l'assembly par rapport aux dernières copies des modules fournis. Étant donné qu'il peut y avoir des fonctions CLR, des procédures stockées, des déclencheurs, des types de données et des fonctions d'agrégation définies par l'utilisateur dans l'instance de SQL Server qui sont déjà définies par rapport à l'assembly, l'instruction ALTER ASSEMBLY les lie à la dernière implémentation de l'assembly. Pour effectuer cette liaison, les méthodes mappées aux fonctions CLR, aux procédures stockées et aux déclencheurs doivent toujours exister dans l'assembly modifié avec les mêmes signatures. Les classes qui implémentent les types définis par l'utilisateur CLR et les fonctions d'agrégation définies par l'utilisateur doivent toujours satisfaire aux exigences pour être un type ou un agrégat défini par l'utilisateur.

Un des exemples sur la même page semble faire l'affaire:

ALTER ASSEMBLY ComplexNumber 
FROM 'C:\Program Files\Microsoft SQL Server\90\Tools\Samples\1033\Engine\Programmability\CLR\UserDefinedDataType\CS\ComplexNumber\obj\Debug\ComplexNumber.dll' 
Ben Thul
la source
1
Cela peut-il être fait lorsque l'assembly mis à jour se trouve sur la machine client SSMS plutôt que sur la machine hôte SQL Server? Je n'ai pas les privilèges suffisants sur le serveur pour accéder directement à son système de fichiers, mais j'ai les droits suffisants pour ajouter et supprimer des assemblys CLR.
Zarepheth
Eh bien, la plupart du temps non. Vous pouvez spécifier un chemin UNC (c'est-à-dire \\ serveur \ chemin \ vers \ fichier) et tant que le compte de service sous lequel le moteur SQL s'exécute dispose d'autorisations de lecture sur le fichier, cela devrait fonctionner. L'autre option consiste à spécifier la valeur binaire de l'assembly. Si vous l'avez déjà déployé sur un autre serveur, l'écriture de l'alter à partir de là vous donnera la valeur de blob.
Ben Thul
Ouais, c'est ce que je pensais. :( Peut-être qu'une version plus récente de SSMS permettra la mise à jour des assemblys à partir d'une machine distante. En attendant, je suppose que je supprime et crée des assemblys via l'interface graphique SSMS - et effectue des opérations DROP et CREATE pour toutes les fonctions dépendantes.
Zarepheth
Je ne retiendrais pas mon souffle sur celui-là. En ce qui concerne la suppression et la recréation, pourquoi ne pouvez-vous pas exercer l'une des méthodes décrites ci-dessus?
Ben Thul
1
"L'ajout et la modification d'assemblys nécessite une référence de système de fichiers." - ce n'est pas vrai. Les deux CREATE ASSEMBLYet ALTER ASSEMBLYprendront un blob qui représente l'assembly. Prouvez-le vous-même en accédant à n'importe quelle base de données créée sur 2008+ et accédez à Programmabilité -> Assemblys et créez un script pour la création de l'assembly Microsoft.SqlServer.Types. Ce gigantesque varbinaire est l'assemblage . Comme cela s'applique à votre situation, déployez votre assembly sur votre instance locale, créez un ALTER ASSEMBLYscript et faites-en un script.
Ben Thul
7

Pour compléter la réponse de Ben Thul, cela peut être accompli à distance assez facilement via l'interface graphique de SQL Server Management Studio .

  1. Sous l'Explorateur d'objets pour votre base de données -> Programmabilité, cliquez avec le bouton droit sur Assemblys et sélectionnez 'New Assembly ...'.

  2. Accédez à votre DLL mise à jour.

  3. Au lieu de cliquer sur «OK» (ce qui échouera, car un assemblage du même nom existe déjà), cliquez sur «Script» en haut de la fenêtre Nouvel assemblage.
     
    Vous serez déposé dans une requête SQL qui comprend une ligne 'CREATE ASSEMBLY' suivie d'un énorme blob qui est la DLL que vous venez de sélectionner.

  4. Changez 'CREATE' en 'ALTER' puis exécutez!

Le script a également créé une ligne «AUTORISATION» pour moi que j'ai dû supprimer avant de l'exécuter; votre kilométrage peut varier.

J'espère que cela aide quelqu'un d'autre sans accès au système de fichiers à ses serveurs.

Espérons que Microsoft en fera un jour une opération de première classe dans SSMS, mais c'est une solution de contournement assez facile jusqu'à ce qu'ils le fassent.

F. Shinn
la source
1

j'ai trouvé un indice sur la réponse sur Stackoverflow :

ALTER ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';
Ian Boyd
la source
1
Vous ALTER ASSEMBLYUPDATEALTER
vouliez