Cómo actualizar un ensamblado CLR sin soltar el ensamblaje desde SQL Server

18

¿Cómo puedo actualizar un dll de ensamblaje de función (o procedimiento) CLR sin tener que soltar y volver a crear el ensamblaje en SQL Server (2008 R2)?

Tal como está ahora si actualizo un ensamblaje (por ejemplo, para agregar una nueva función), SQL Server no respetará el dll actualizado hasta que deje el ensamblaje:

DROP ASSEMBLY CLRFunctions

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

Pero antes de que pueda soltar el ensamblaje, primero debo soltar todas las funciones que hacen referencia a él:

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

Y luego puedo soltar el ensamblaje:

DROP ASSEMBLY CLRFunctions

Ahora tengo que " crear " el ensamblaje:

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

Y ahora tengo que buscar la declaración de todos los UDF que se registraron antes de eliminarlos.

Prefiero actualizar un ensamblado y hacer que SQL Server comience a usarlo.


Actualización : al azar intenté DBCC FREEPROCCACHEforzar una "recompilación", pero SQL Server todavía usa el código anterior.

Actualización : eliminé el dll de ensamblado CLRFunctions.dlly SQL Server aún puede ejecutar el código (sin código, eso debería ser imposible).

Ian Boyd
fuente

Respuestas:

16

Creo que lo estás buscando alter assembly. De BOL:

Si se especifica la cláusula FROM, ALTER ASSEMBLY actualiza el ensamblaje con respecto a las últimas copias de los módulos provistos. Debido a que puede haber funciones CLR, procedimientos almacenados, disparadores, tipos de datos y funciones agregadas definidas por el usuario en la instancia de SQL Server que ya están definidas en el ensamblado, la instrucción ALTER ASSEMBLY los vuelve a unir a la última implementación del ensamblaje. Para lograr esta nueva vinculación, los métodos que se asignan a funciones CLR, procedimientos almacenados y disparadores deben existir en el ensamblado modificado con las mismas firmas. Las clases que implementan tipos CLR definidos por el usuario y funciones agregadas definidas por el usuario aún deben cumplir los requisitos para ser un tipo o agregado definido por el usuario.

Parece que uno de los ejemplos en la misma página funcionaría:

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
fuente
1
¿Se puede hacer esto cuando el ensamblado actualizado se encuentra en la máquina cliente SSMS en lugar de la máquina host de SQL Server? No tengo suficientes privilegios en el servidor para acceder directamente a su sistema de archivos, pero sí tengo suficientes derechos para agregar y eliminar ensamblados CLR.
Zarepheth
No. Bueno, mayormente no. Puede especificar una ruta UNC (es decir, \\ servidor \ ruta \ a \ archivo) y siempre que la cuenta de servicio con la que se ejecuta el motor SQL tenga permisos de lectura en el archivo, debería funcionar. La otra opción es especificar el valor binario para el ensamblaje. Si ya lo tiene implementado en otro servidor, la secuencia de comandos desde el alter obtendrá el valor de blob.
Ben Thul
Sí, eso es lo que yo pensaba. :( Quizás una versión más nueva de SSMS permitirá actualizar los ensamblajes desde una máquina remota. Mientras tanto, supongo que descarto y creo ensamblajes a través de la GUI de SSMS, y realizo operaciones DROP y CREATE para todas las funciones dependientes.
Zarepheth
No aguantaría la respiración en eso. En cuanto a tener que soltar y recrear, ¿por qué no puede ejercer ninguno de los métodos descritos anteriormente?
Ben Thul
1
"Agregar y modificar ensamblajes requiere una referencia del sistema de archivos". - esto no es verdad. Ambos CREATE ASSEMBLYy ALTER ASSEMBLYtomarán una gota que representa la asamblea. Pruébelo usted mismo yendo a cualquier base de datos creada en 2008+ y vaya a Programabilidad -> Ensamblajes y cree la creación del ensamblado Microsoft.SqlServer.Types. Ese varbinary gigantesco es el ensamblaje . Como esto se aplica a su situación, implemente su ensamblado en su instancia local, escríbalo y conviértalo en un ALTER ASSEMBLYscript.
Ben Thul
7

Para agregar a la respuesta de Ben Thul, esto se puede lograr de forma remota con bastante facilidad a través de la GUI de SQL Server Management Studio .

  1. Bajo el Explorador de objetos para su base de datos -> Programabilidad, haga clic derecho en Ensamblajes y seleccione 'Nuevo ensamblaje ...'.

  2. Busque su DLL actualizada.

  3. En lugar de hacer clic en 'Aceptar' (que fallará, ya que ya existe un ensamblaje con el mismo nombre), haga clic en 'Script' en la parte superior de la ventana Nuevo ensamblaje.
     
    Se lo colocará en una consulta SQL que incluye una línea 'CREAR ENSAMBLAJE' seguida de un gran blob que es la DLL que acaba de seleccionar.

  4. ¡Cambie 'CREAR' a 'ALTERAR' y luego ejecute!

El Script también creó una línea de 'AUTORIZACIÓN' para mí que tuve que eliminar antes de ejecutar; Su kilometraje puede variar.

Espero que esto ayude a alguien más sin acceso al sistema de archivos a sus servidores.

Esperemos que Microsoft haga de esta una operación de primera clase en SSMS algún día, pero esta es una solución bastante fácil hasta que lo hagan.

F. Shinn
fuente
1

Encontré una pista sobre la respuesta en Stackoverflow :

ALTER ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';
Ian Boyd
fuente
1
ALTER ASSEMBLYUPDATEALTER
Querías