Come aggiornare un assembly CLR senza eliminare l'assembly da SQL Server


18

Come posso aggiornare una DLL di assembly (o procedura) CLR senza dover eliminare e ricreare l'assembly in SQL Server (2008 R2)?

Così com'è ora se aggiorno un assembly (ad esempio per aggiungere una nuova funzione), SQL Server non rispetterà la dll aggiornata fino a quando non lascerò cadere l'assembly:

DROP ASSEMBLY CLRFunctions

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

Ma prima di poter rilasciare l'assembly, devo prima eliminare tutte le funzioni che lo fanno riferimento:

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

E poi posso rilasciare l'assemblaggio:

DROP ASSEMBLY CLRFunctions

Ora devo " creare " l'assemblaggio:

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

E ora devo dare la caccia alla dichiarazione di tutti gli UDF che sono stati registrati prima di cancellarli.

preferirei aggiornare un assembly e fare in modo che SQL Server inizi a utilizzarlo.


Aggiornamento : ho provato casualmente DBCC FREEPROCCACHEa forzare un "ricompilare", ma SQL Server utilizza ancora il vecchio codice.

Aggiornamento : ho eliminato l'assembly dll CLRFunctions.dlle SQL Server è ancora in grado di eseguire il codice (senza codice che dovrebbe essere impossibile).

Risposte:


16

Penso che tu stia cercando alter assembly. Da BOL:

Se viene specificata la clausola FROM, ALTER ASSEMBLY aggiorna l'assembly rispetto alle ultime copie dei moduli forniti. Poiché potrebbero esserci funzioni CLR, stored procedure, trigger, tipi di dati e funzioni aggregate definite dall'utente nell'istanza di SQL Server che sono già definite rispetto all'assembly, l'istruzione ALTER ASSEMBLY le associa all'ultima implementazione dell'assembly. Per realizzare questa associazione, i metodi associati alle funzioni CLR, alle stored procedure e ai trigger devono ancora esistere nell'assieme modificato con le stesse firme. Le classi che implementano i tipi CLR definiti dall'utente e le funzioni aggregate definite dall'utente devono comunque soddisfare i requisiti per essere un tipo o aggregato definito dall'utente.

Uno degli esempi sulla stessa pagina sembra che farebbe il trucco:

ALTER ASSEMBLY ComplexNumber 
FROM 'C:\Program Files\Microsoft SQL Server\90\Tools\Samples\1033\Engine\Programmability\CLR\UserDefinedDataType\CS\ComplexNumber\obj\Debug\ComplexNumber.dll' 

1
È possibile farlo quando l'assembly aggiornato si trova sul computer client SSMS anziché sul computer host di SQL Server? Non ho privilegi sufficienti sul server per accedere direttamente al suo file system, ma ho diritti sufficienti per aggiungere e rimuovere gli assembly CLR.
Zarepheth,

No. Beh, per lo più no. È possibile specificare un percorso UNC (ovvero \\ server \ percorso \ su \ file) e fintanto che l'account del servizio su cui è in esecuzione il motore SQL ha autorizzazioni di lettura sul file, dovrebbe funzionare. L'altra opzione è specificare il valore binario per l'assembly. Se lo hai già distribuito su un altro server, lo scripting dell'alter da lì ti darà il valore BLOB.
Ben giovedì

Sì, è quello che ho pensato. :( Forse una versione più recente di SSMS consentirà l'aggiornamento degli assembly da una macchina remota. Nel frattempo, immagino di rilasciare e creare assembly tramite la GUI di SSMS - ed eseguire operazioni DROP e CREATE per tutte le funzioni dipendenti.
Zarepheth

Non trattengo il respiro su quello. Per quanto riguarda la necessità di abbandonare e ricreare, perché non è possibile esercitare uno dei metodi descritti sopra?
Ben giovedì

1
"L'aggiunta e la modifica di assiemi richiede un riferimento al file system." - questo non è vero. Entrambi CREATE ASSEMBLYe ALTER ASSEMBLYprenderanno un BLOB che rappresenta l'assemblaggio. Dimostralo a te stesso andando su qualsiasi database creato nel 2008+ e vai su Programmabilità -> Assiemi e script per la creazione dell'assembly Microsoft.SqlServer.Types. Quel gigantesco varbinary è l'assemblea . Poiché ciò si applica alla tua situazione, distribuisci l'assembly nell'istanza locale, esegui lo script e rendilo uno ALTER ASSEMBLYscript.
Ben giovedì

7

Per aggiungere alla risposta di Ben Thul, ciò può essere realizzato in remoto abbastanza facilmente tramite la GUI di SQL Server Management Studio .

  1. Sotto Esplora oggetti per il tuo database -> Programmabilità, fai clic con il pulsante destro del mouse su Assiemi e seleziona "Nuovo assieme ...".

  2. Passare alla DLL aggiornata.

  3. Invece di fare clic su "OK" (che non riuscirà, poiché esiste già un assembly con lo stesso nome) fare clic su "Script" nella parte superiore della finestra Nuovo assieme.
     
    Verrai inserito in una query SQL che include una riga 'CREATE ASSEMBLY' seguita da un enorme BLOB che è la DLL appena selezionata.

  4. Cambia 'CREA' in 'ALTER' e quindi esegui!

Lo script ha anche creato per me una riga "AUTORIZZAZIONE" che ho dovuto rimuovere prima di eseguire; il tuo chilometraggio può variare.

Spero che questo aiuti qualcun altro senza l'accesso al filesystem ai loro server.

Si spera che un giorno Microsoft lo renderà un'operazione di prima classe in SSMS, ma è una soluzione abbastanza semplice fino a quando non lo farà.


1

ho trovato un suggerimento sulla risposta su Stackoverflow :

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

1
ALTER ASSEMBLYUPDATEALTER
Volevi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.