Einrichten einer zentralen CLR-Bibliothek für gespeicherte Prozeduren / Funktions-Respositorys für interne gespeicherte Prozesse in anderen Datenbanken zur Verwendung?


17

Ich möchte Code verwenden, den ich in C # CLR entwickelt habe, um ihn in allen Datenbanken des Systems zu verwenden, damit ich nicht jeden auf vertrauenswürdig einstellen und CLR einschalten und in jeder eine Menge des gleichen Codes behalten muss .

Gibt es eine beste Möglichkeit, dies aus administrativer und sicherheitstechnischer Sicht zu tun? Die CLR-Funktionen sind sehr einfach wie String-Breaker, E-Mail-Validierung, URL-En / Decodierung, Base64 usw. Ich möchte, dass nur das DBO-Schema in jeder Datenbank auf die Funktionen zugreifen kann.

  1. Gibt es eine einfache Möglichkeit, dies zu tun?
  2. Außerdem ist mir nicht klar, ob die CLR-DLL eingebettet ist und ob ich die Datenbank verschiebe, sie mitliefert oder ob ich die DLL ebenfalls verschieben muss.

Vielen Dank


1
OK, klingt gut. Solange ich keine Grillen aus der toten Stille über die Frage höre. Hatte immer Glück beim Stackoverflow
Alex Erwin

1
dba.se ist weniger verrückt als SO, aber ich bin zuversichtlich, dass Sie innerhalb eines Tages oder so gute Aufmerksamkeit auf eine Frage wie diese bekommen werden. Bist du glücklich, so lange geduldig zu sein?
Jack Douglas

Lol, Geduld ist eine Tugend. Ich habe eine ganze Menge davon und die Frage selbst, würde ich denken, würde MS ansprechen. Was ist, wenn Sie ein SQL Server-Host sind, der einige nützliche Funktionen bereitstellen möchte, Ihren Server jedoch nicht in vollem Umfang für CLR geöffnet hat?
Alex Erwin

Antworten:


8

In unserer Firma haben wir genau dieses Setup. Wenn Sie eine CLR-Assembly erstellen, wird eine binäre Darstellung der Assembly in der Datenbank gespeichert, in der Sie sie erstellen. Auf diese Weise können Sie sie mitnehmen (und sogar per Skript ausführen), falls Sie die Datenbank zu einem beliebigen Zeitpunkt verschieben.

Vor ein paar Monaten war unser Rechenzentrum überfüllt - es füllte mehrere Server mit Wasser. Als ich sie wieder aufbaute, habe ich nur die Backups der Datenbank verwendet, die in der Nacht zuvor aufgenommen wurden. Bisher hatten wir keine Probleme .. (Holz anfassen!)

Ich bin nicht sicher, ob dies aus Sicherheitssicht das Richtige ist, aber die Art und Weise, wie wir den Zugriff auf CLR-Prozesse usw. gewähren, besteht darin, eine Rolle in der gemeinsam genutzten Datenbank zu erstellen und dieser Rolle dann Benutzer aus anderen Datenbanken hinzuzufügen. Die Rolle wird dann auf den CLR-Prozessen ausgeführt.

Möglicherweise treten Zugriffsprobleme auf, wenn die CLR versucht, auf Ressourcen außerhalb der Datenbank zuzugreifen, in der sie enthalten ist. Sie können jedoch die Berechtigung für die Assembly festlegen, wenn Sie sie erstellen. Der folgende Link enthält viel mehr Informationen zu Berechtigungen, als ich hier erklären kann:

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

Ich hoffe das hilft dir.


6

Die Assembly-Binärdatei wird als Blob in der Datenbank gespeichert, sodass sie überall in der Datenbank gespeichert wird. CLR ist nur für die Instanz aktiviert - dafür gibt es keine datenbankspezifischen Einstellungen.

Warum versuchst du es auf jeden Fall?

(Ich versuche nicht, argumentativ zu sein. Ich möchte nur die Gründe dafür herausfinden, weil das Problem möglicherweise auf eine andere Art und Weise gelöst werden könnte, die Ihren Bedürfnissen entspricht.)


Es gibt keine einfache Möglichkeit, dies zu tun, außer die Assembly in eine gemeinsam genutzte Datenbank zu stellen.

Trotzdem halte ich es für vorteilhaft, die datenbankzentrierte Architektur zu nutzen, es sei denn, es gibt eine bestimmte Situation, die sehr zwingende Gründe für eine Zentralisierung hat. Der Grund dafür ist, dass das Verschieben der Assembly (oder anderer Elemente) außerhalb der Datenbank zu einer Abhängigkeit in Ihrer Umgebung führt. Dies ist genau der umgekehrte Ansatz, auf den Microsoft ab SQL Server 2012 bei enthaltenen Datenbanken setzt.

  • Wenn Sie Funktionen wie Replikation oder Clustering benötigen, kann diese Abhängigkeit die Bereitstellung, aber auch die Fehlerbehebung und Failover-Prozeduren erheblich komplexer gestalten.

  • Diese Architektur ist für Leute, die mit dem System nicht vertraut sind, viel weniger offensichtlich (dh sie ist weniger selbstentdeckbar und weniger selbstdokumentierend).

  • Wenn Sie in verschiedenen Datenbanken unterschiedliche Sicherheitsanforderungen haben oder wenn Sie etwas mit Variationen zu tun haben, befinden Sie sich in einer Welt voller Verletzungen.

  • Wenn diese Datenbanken für Kunden bereitgestellt werden (das hört sich so an, als ob dies nicht der Fall wäre, aber der Vollständigkeit halber sage ich das), erhöht dies die Komplexität des Bereitstellungsverfahrens, der Wartung und der Fehlerbehebung.

  • Da alle Datenbanken diesen Code gemeinsam nutzen, können bei Auftreten (oder Behebung!) Von Fehlern möglicherweise alle Anwendungen beschädigt werden, die auf die Datenbanken angewiesen sind. Umfassende Unit-Tests wären ein absolutes Muss.

Wenn Sie über mehrere Datenbanken verfügen, für die dieselbe Funktionalität erforderlich ist, gibt es andere Möglichkeiten, um die Anzahl der Duplikate zu verringern. Ich gehe davon aus, dass dies der Sinn der Übung ist. Sogar eine recht komplexe CLR-Assembly nimmt im Vergleich zu den Daten in der Datenbank selbst (fast immer) nicht viel physischen Speicherplatz ein. Daher sehe ich das nicht als gültiges Argument, es sei denn, Sie haben buchstäblich Tausende winziger Datenbanken, die dies benötigen Versammlung.

Sie können andere Teile der Bereitstellungsprozedur für diese Datenbanken ändern, um die Duplizierung der Quelle zu verringern. Erstellen und implementieren Sie die Assembly beispielsweise am gemeinsamen Speicherort des CLR-Codes in der Quellcodeverwaltung. Oder erstellen Sie ein Skript, das dieselbe Assembly für die Datenbanken bereitstellt. Automatisieren Sie diesen Teil der Dinge so weit wie möglich und es wird keine große Sache.

Ich bin damit einverstanden, dass das, was ich vorschlage, ein Kompromiss ist, da es immer noch einige Überschneidungen geben wird, aber das muss mit den negativen Aspekten in Verbindung gebracht werden, die mit der Implementierung einer Architektur verbunden sind, die nicht dem vorgeschriebenen Standard entspricht. Nur Sie können entscheiden, was für Ihre Umgebung richtig ist.


Ich sehe Ihren Standpunkt darin, möglicherweise Dinge zu brechen, es ist jedoch die Vereinfachung des Rollouts von Code. Keine Armee von Entwicklern hier. Nur ich. Ich habe jedoch andere Benutzer, die die Datenbank verwenden, daher muss sichergestellt werden, dass auf die Funktionen nur zugegriffen werden kann, wenn sie von gespeicherten Prozeduren verwendet werden, die ich definiere.
Alex Erwin

1

Wie die beiden anderen Antworten richtig Zustand, Baugruppen werden in eine bestimmte Datenbank geladen und sind nicht systemweit (obwohl ich ziemlich sicher bin , dass der assembly_idWert ist einzigartig systemweit). Dies bedeutet, dass sie mit jeder Datenbank, in die sie geladen werden, gesichert und wiederhergestellt werden.

Auch die enabled/ disabledEinstellung von CLR Integration(über sp_configure) ist systemweit. Als Randnotiz gilt diese Einstellung nur für vom Benutzer erstellte CLR-Funktionen. CLR ist im Allgemeinen immer aktiviert, da bestimmte integrierte Funktionen davon abhängen.

Die beiden anderen Antworten hier geben zwar gültige Punkte an, diese Punkte sind jedoch nicht SQLCLR-spezifisch, und die für den SQLCLR-Code spezifischen Faktoren für diese Entscheidung werden nicht erwähnt. Es sind Speicherprobleme zu berücksichtigen, wenn Sie Code für jede einzelne Datenbank bereitstellen (vorausgesetzt, Sie haben viele Datenbanken), potenzielle Probleme mit Ressourcenkonflikten, potenzielle sicherheitsrelevante Probleme usw.

Ich habe eine umfassende Liste von Dingen bereitgestellt, die speziell für SQLCLR-Code bei der Entscheidung zwischen einer zentralisierten Datenbank und einer individuellen Datenbankbereitstellung zu beachten sind. Anstatt die Liste hier zu duplizieren, lesen Sie bitte die folgende Antwort (auch hier auf DBA.SE):

Wie kann die CLR-Funktion unter Leistungsgesichtspunkten besser genutzt werden (Wiederholung in jeder Datenbank oder allgemeine Funktion)?

In einem ähnlichen Zusammenhang würde ich auch die Frage stellen, warum eine Datenbank auf festgelegt wird TRUSTWORTHY ON. Die in der Frage genannten Funktionen (z. B. "Zeichenfolgenunterbrecher, E-Mail-Überprüfung, URL de / decodieren, base64 usw.") sind in einer SAFEAssembly alle möglich . Sie sollten auch nicht die Verwendung EXTERNAL_ACCESSoder UNSAFEperission_set Werte , wenn es unbedingt notwendig ist . Und wenn es für eine bestimmte Anzahl von Funktionen , die notwendig ist, werden diese sollten dann in einer separaten Assembly , die nur enthält SAFECode , so dass keine skalare Funktionen, die nicht über den Datenzugriff tun und wie sie markiert in IsDeterministic = trueder Lage, Nutzung des Performance - Vorteils des Seins zu machen in der Lage, an parallelen Plänen teilzunehmen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.