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.
- Gibt es eine einfache Möglichkeit, dies zu tun?
- 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
sql-server
sql-server-2008
sql-server-2008-r2
c#
sql-clr
Alex Erwin
quelle
quelle
Antworten:
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.
quelle
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.
quelle
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_id
Wert ist einzigartig systemweit). Dies bedeutet, dass sie mit jeder Datenbank, in die sie geladen werden, gesichert und wiederhergestellt werden.Auch die
enabled
/disabled
Einstellung vonCLR Integration
(übersp_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 einerSAFE
Assembly alle möglich . Sie sollten auch nicht die VerwendungEXTERNAL_ACCESS
oderUNSAFE
perission_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ältSAFE
Code , so dass keine skalare Funktionen, die nicht über den Datenzugriff tun und wie sie markiert inIsDeterministic = true
der Lage, Nutzung des Performance - Vorteils des Seins zu machen in der Lage, an parallelen Plänen teilzunehmen.quelle