¿Está configurando una biblioteca de depósito de función / procedimiento almacenado CLR central para utilizar los procedimientos almacenados internos en otras bases de datos?


17

Me gustaría usar el código que desarrollé en C # CLR para usarlo en todas las bases de datos del sistema, de modo que no tenga que configurar cada uno como confiable y activar CLR y mantener un montón del mismo código dentro de cada uno .

¿Hay una mejor manera de hacer esto desde un punto de vista administrativo y de seguridad? Las funciones de CLR son muy básicas como interruptores de cadena, validación de correo electrónico, url en / decode, base64, etc. Me gustaría que solo el esquema dbo en cada base de datos pueda acceder a las funciones.

  1. ¿Hay alguna forma simple de hacer esto?
  2. Además, no tengo claro si el dll de CLR está incrustado y si muevo la base de datos, se etiqueta o debo mover el dll también.

Gracias


1
OK suena bien. Mientras no escuche grillos del silencio muerto sobre la pregunta. Siempre tuve suerte en stackoverflow
Alex Erwin

1
dba.se está menos frenético que SO, pero estoy seguro de que recibirá una buena atención en una pregunta como esta dentro de un día más o menos. ¿Estás feliz de ser paciente tanto tiempo?
Jack dice que intente topanswers.xyz

Jajaja, la paciencia es una virtud. Tengo una buena cantidad, y la pregunta en sí, creo, que MS abordaría. ¿Qué sucede si usted es un host de SQL Server que quiere exponer algunas funciones útiles pero no tiene su servidor abierto a CLR con toda su fuerza?
Alex Erwin

Respuestas:


8

En nuestra empresa tenemos esa configuración exacta. Cuando crea un ensamblaje CLR, se almacena una representación binaria del ensamblaje dentro de la base de datos en la que lo crea. Esto le permite llevarlo con usted (e incluso escribirlo) si mueve la base de datos en cualquier momento.

Hace un par de meses, nuestro centro de datos se inundó, llenando varios servidores de agua. Cuando los reconstruí, solo usé las copias de seguridad de la base de datos que se habían tomado la noche anterior. Hasta ahora no hemos tenido problemas ... (¡toca la madera!)

No estoy seguro de si esto es lo correcto desde una perspectiva de seguridad, pero la forma en que otorgamos acceso a los procesos CLR, etc. es crear un rol dentro de la base de datos compartida y luego agregar usuarios de otras bases de datos a ese rol. El rol se otorga ejecutar en los procesos CLR.

Puede haber problemas de acceso si el CLR está tratando de hacer cosas como acceder a recursos fuera de la base de datos que contiene, pero puede configurar el permiso en el ensamblado cuando lo crea. Sin embargo, el siguiente enlace tiene mucha más información sobre permisos que la que puedo explicar aquí:

http://msdn.microsoft.com/en-us/library/ms345101.aspx

Espero que esto te ayude.


6

El ensamblado binario se almacena como un blob en la base de datos, por lo que se transporta a donde vaya la base de datos. CLR solo está habilitado en la instancia ; no hay configuraciones específicas de la base de datos para eso.

En cualquier caso, ¿por qué estás tratando de hacer esto?

(No estoy tratando de ser discutidor; solo quiero escuchar los motivos involucrados, porque tal vez el problema podría resolverse de una manera diferente que satisfaga sus necesidades).


No hay forma de hacerlo fácilmente, excepto colocar el ensamblado en una base de datos compartida.

Dicho esto, creo que es ventajoso adoptar la arquitectura centrada en la base de datos, a menos que haya una situación particular que tenga razones muy convincentes para centralizar. La razón es que colocar el ensamblaje (o cualquier otra cosa) fuera de la base de datos crea una dependencia en su entorno. Este es precisamente el enfoque opuesto hacia el cual Microsoft está construyendo con bases de datos contenidas a partir de SQL Server 2012.

  • Cuando empiece a necesitar usar funciones como la replicación o la agrupación en clúster, esta dependencia puede agregar una enorme cantidad de complejidad a la implementación, pero también a la resolución de problemas y los procedimientos de conmutación por error.

  • Esta arquitectura es mucho menos obvia para las personas que no están familiarizadas con el sistema (es decir, es menos reconocible por sí mismo y menos autodocumentado).

  • Si terminas requiriendo una seguridad diferente en diferentes bases de datos, o cualquier cosa que implique variación, estás en un mundo de dolor.

  • Si estas bases de datos se implementan en los clientes (parece que no lo serán, pero lo diré por completo), esto agrega complejidad al procedimiento de implementación, mantenimiento y solución de problemas.

  • Dado que todas las bases de datos compartirían este código, si se introducen errores (¡o se corrigen!), Esto podría romper todas las aplicaciones que dependen de las bases de datos. La prueba unitaria integral sería una necesidad absoluta.

Si tiene varias bases de datos que necesitan la misma funcionalidad, existen otras formas de reducir la cantidad de duplicaciones involucradas, lo que supongo que es el objetivo del ejercicio. Incluso un ensamblado CLR bastante complejo no ocupará mucho espacio de almacenamiento físico en comparación con los datos en la base de datos en sí (casi siempre), por lo que no lo veo como un argumento válido a menos que tenga literalmente miles de pequeñas bases de datos que necesitan esto montaje.

Lo que podría hacer es modificar otras partes del procedimiento de implementación para estas bases de datos para reducir la duplicación de origen. Por ejemplo, compile e implemente el ensamblaje desde la ubicación común del código CLR en el control de origen. O cree un script que implemente el mismo ensamblaje en las bases de datos. Automatice esta parte de las cosas tanto como sea posible, y no será un gran problema.

Estoy de acuerdo en que lo que estoy sugiriendo es una compensación, porque todavía habrá cierta duplicación, pero eso debe equilibrarse con los aspectos negativos relacionados con la implementación de una arquitectura que no sigue el estándar prescrito. Solo usted puede decidir qué es lo correcto para su entorno.


Veo su punto con posiblemente romper cosas, sin embargo, es simplificar la implementación del código. No hay ejército de desarrolladores aquí. Solo yo. Sin embargo, tengo otros que usan la base de datos, por lo que debo asegurarme de que las funciones sean inaccesibles a menos que se utilicen a partir de los procedimientos almacenados que defino.
Alex Erwin

1

Como las otras dos respuestas indican correctamente, los ensamblados se cargan en una base de datos particular y no son de todo el sistema (aunque estoy bastante seguro de que el assembly_idvalor es único en todo el sistema). Esto significa que están respaldados y restaurados con cada base de datos en la que están cargados.

Además, la configuración enabled/ disabledde CLR Integration(via sp_configure) es para todo el sistema. Como nota al margen, esa configuración es solo para la funcionalidad CLR creada por el usuario ; CLR en un sentido general siempre está habilitado ya que ciertas funciones integradas dependen de ello.

Dicho esto, mientras que las otras dos respuestas aquí hacen puntos válidos, esos puntos no son específicos de SQLCLR, y no se mencionan los factores en la toma de esta decisión que son específicos del código SQLCLR. Hay problemas de memoria a considerar si implementa código en cada base de datos individual (suponiendo que tenga muchas bases de datos), posibles problemas de contención de recursos, posibles problemas relacionados con la seguridad, etc.

He proporcionado lo que debería ser una lista completa de cosas a tener en cuenta, específicamente para el código SQLCLR, al decidir entre una base de datos centralizada o una implementación de base de datos individual. En lugar de duplicar la lista aquí, consulte la siguiente respuesta (también aquí en DBA.SE):

¿Cómo utilizar mejor la función CLR desde el punto de vista del rendimiento (repetir dentro de cada DB o tener una función general)?

Además, en una nota relacionada, me preguntaría por qué se está configurando una base de datos TRUSTWORTHY ON. La funcionalidad indicada en la pregunta (es decir, "interruptores de cadena, validación de correo electrónico, url en / decode, base64, etc.") es posible dentro de un SAFEensamblado. No debe usar los valores EXTERNAL_ACCESSo UNSAFEperission_set a menos que sea absolutamente necesario. Y si es necesario para un cierto número de funciones, entonces esas deben estar en una Asamblea separada que contenga solo SAFEcódigo de manera que cualquier función escalar que no acceda a los datos y esté marcada como IsDeterministic = truepodrá aprovechar el beneficio de rendimiento de ser capaz de participar en planes paralelos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.