Mise en place d'une bibliothèque centrale de procédures / fonctions stockées CLR pour les proc stockés dans d'autres bases de données à utiliser?


17

Je voudrais utiliser le code que j'ai développé en C # CLR pour être utilisé dans toutes les bases de données du système afin de ne pas avoir à définir chacun comme digne de confiance et activer CLR et garder un tas du même code à l'intérieur de chacun .

Existe-t-il un meilleur moyen de le faire d'un point de vue administratif et sécuritaire? Les fonctions CLR sont très basiques comme les disjoncteurs de chaîne, la validation des e-mails, l'url en / décode, base64, etc. Je voudrais que seul le schéma dbo dans chaque base de données puisse accéder aux fonctions.

  1. Existe-t-il un moyen simple de procéder?
  2. De plus, je ne sais pas si la DLL CLR est intégrée et si je déplace la base de données, elle balise le long, ou dois-je également déplacer la DLL.

Merci


1
Ça a l'air bien. Tant que je n'entends pas les grillons du silence de mort sur la question. Toujours eu de la chance à stackoverflow
Alex Erwin

1
dba.se est moins frénétique que SO, mais je suis convaincu que vous obtiendrez une bonne attention sur une question comme celle-ci dans un jour ou deux. Êtes-vous heureux d'être patient aussi longtemps?
Jack Douglas

Lol, la patience est une vertu. J'en ai une bonne quantité, et la question elle-même, je pense, répondrait à MS. Que faire si vous êtes un hôte SQL Server qui souhaite exposer certaines fonctions utiles mais que votre serveur n'est pas ouvert à CLR en force?
Alex Erwin

Réponses:


8

Dans notre entreprise, nous avons cette configuration exacte. Lorsque vous créez un assembly CLR, une représentation binaire de l'assembly est stockée dans la base de données dans laquelle vous le créez. Cela vous permet de l'emporter avec vous (et même de l'écrire) si vous déplacez la base de données à tout moment.

Il y a quelques mois, notre centre de données a été inondé - remplissant plusieurs serveurs pleins d'eau. Lorsque je les ai reconstruits, je n'ai utilisé que les sauvegardes de la base de données qui avaient été prises la veille. Jusqu'à présent, nous n'avons eu aucun problème .. (touchez le bois!)

Je ne sais pas si c'est la bonne chose à faire du point de vue de la sécurité, mais la façon dont nous accordons l'accès aux procs CLR, etc. est de créer un rôle dans la base de données partagée, puis d'ajouter des utilisateurs d'autres bases de données à ce rôle. Le rôle est ensuite accordé exécuter sur les procs CLR.

Il peut y avoir des problèmes d'accès si le CLR essaie de faire des choses comme accéder aux ressources en dehors de la base de données dans laquelle il est contenu, mais vous pouvez définir l'autorisation sur l'assembly lorsque vous le créez. Le lien ci-dessous contient beaucoup plus d'informations sur les autorisations que je ne peux l'expliquer ici:

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

J'espère que cela vous aide.


6

Le binaire d'assembly est stocké comme un blob dans la base de données, il est donc transporté partout où la base de données va. CLR n'est activé que sur l' instance - il n'y a pas de paramètres spécifiques à la base de données pour cela.

Dans tous les cas, pourquoi essayez-vous de faire cela?

(Je n'essaie pas d'être argumentatif; je veux juste entendre les motifs impliqués, parce que peut-être le problème pourrait être résolu d'une manière différente qui répond à vos besoins.)


Il n'y a aucun moyen de le faire facilement, sauf pour placer l'assembly dans une base de données partagée.

Cela dit, je pense qu'il est avantageux d'adopter l'architecture centrée sur la base de données, à moins qu'il n'y ait une situation particulière qui a des raisons très impérieuses de centraliser. La raison en est que le fait de placer l'assembly (ou quoi que ce soit d'ailleurs) en dehors de la base de données crée une dépendance dans votre environnement. Il s'agit précisément de l'approche inverse que Microsoft met en place avec les bases de données contenues à partir de SQL Server 2012.

  • Lorsque vous commencez à avoir besoin d'utiliser des fonctionnalités telles que la réplication ou la mise en cluster, cette dépendance peut potentiellement ajouter une énorme quantité de complexité au déploiement, mais également aux procédures de dépannage et de basculement.

  • Cette architecture est beaucoup moins évidente pour les personnes qui ne connaissent pas le système (c'est-à-dire qu'elle est moins auto-détectable et moins auto-documentée).

  • Si vous finissez par exiger une sécurité différente dans différentes bases de données, ou tout ce qui implique des variations, vous êtes dans un monde de mal.

  • Si ces bases de données sont déployées auprès des clients (on dirait qu'elles ne le seront pas, mais je le dirai pour être complet), cela ajoute de la complexité à la procédure de déploiement, à la maintenance et au dépannage.

  • Étant donné que toutes les bases de données partageraient ce code, si des bogues étaient introduits (ou corrigés!), Cela pourrait potentiellement casser toutes les applications qui s'appuient sur les bases de données. Des tests unitaires complets seraient absolument indispensables.

Si vous avez plusieurs bases de données qui ont besoin de la même fonctionnalité, il existe d'autres moyens de réduire la quantité de duplication impliquée, ce qui, je suppose, est le but de l'exercice. Même un assemblage CLR assez complexe ne prendra pas beaucoup d'espace de stockage physique par rapport aux données dans la base de données elle-même (presque toujours), donc je ne vois pas cela comme un argument valide à moins que vous n'ayez littéralement des milliers de petites bases de données qui en ont besoin Assemblée.

Vous pouvez modifier d'autres parties de la procédure de déploiement de ces bases de données pour réduire la duplication source. Par exemple, générez et déployez l'assembly à partir de l'emplacement commun du code CLR dans le contrôle de code source. Ou, créez un script qui déploie le même assembly dans les bases de données. Automatisez autant que possible cette partie des choses, et ce ne sera pas un gros problème.

Je conviens que ce que je propose est un compromis, car il y aura toujours des doubles emplois, mais cela doit être équilibré avec les inconvénients liés à la mise en œuvre d'une architecture qui ne respecte pas la norme prescrite. Vous seul pouvez décider de ce qui convient à votre environnement.


Je vois votre point avec peut-être casser des choses, mais c'est pour simplifier les déploiements de code. Pas d'armée de développeurs ici. Juste moi. Cependant, j'en ai d'autres qui utilisent la base de données, donc je dois m'assurer que les fonctions sont inaccessibles à moins qu'elles ne soient utilisées à partir des procédures stockées que je définis.
Alex Erwin

1

Comme les deux autres réponses l'indiquent correctement, les assemblys sont chargés dans une base de données particulière et ne sont pas à l'échelle du système (bien que je sois assez certain que la assembly_idvaleur est unique à l'échelle du système). Cela signifie qu'ils sont sauvegardés et restaurés avec chaque base de données dans laquelle ils sont chargés.

De plus, le paramètre enabled/ disabledde CLR Integration(via sp_configure) est à l'échelle du système. En remarque, ce paramètre est uniquement pour la fonctionnalité CLR créée par l' utilisateur ; Le CLR dans un sens général est toujours activé car certaines fonctionnalités intégrées en dépendent.

Cela dit, bien que les deux autres réponses ici fassent valoir des points valides, ces points ne sont pas spécifiques au SQLCLR, et il n'y a aucune mention des facteurs de prise de décision qui sont spécifiques au code SQLCLR. Il y a des problèmes de mémoire à considérer si vous déployez du code sur chaque base de données individuelle (en supposant que vous avez plusieurs bases de données), des problèmes potentiels de contention de ressources, des problèmes potentiels liés à la sécurité, etc.

J'ai fourni ce qui devrait être une liste complète de choses à garder à l'esprit, en particulier pour le code SQLCLR, lors du choix entre une base de données centralisée et un déploiement de base de données individuelle. Plutôt que de dupliquer la liste ici, veuillez voir la réponse suivante (également ici sur DBA.SE):

Comment mieux utiliser la fonction CLR du point de vue des performances (répéter à l'intérieur de chaque base de données ou avoir une fonction générale)?

En outre, sur une note connexe, je me demande pourquoi une base de données est définie sur TRUSTWORTHY ON . La fonctionnalité notée dans la question (c'est-à-dire "les disjoncteurs de chaîne, la validation des e-mails, l'url en / décode, base64, etc.") est tout possible au sein d'un SAFEassembly. Vous ne devez pas utiliser les valeurs EXTERNAL_ACCESSou UNSAFEperission_set sauf si cela est absolument nécessaire. Et si cela est nécessaire pour un certain nombre de fonctions, celles-ci doivent être dans un assembly séparé qui ne contient que du SAFEcode de sorte que toutes les fonctions scalaires qui n'accèdent pas aux données et qui sont marquées comme IsDeterministic = truepuissent utiliser l'avantage de performance d'être pouvoir participer à des plans parallèles.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.