Was sind die Vor- und Nachteile, um SQL in gespeicherten Prozessen im Vergleich zu Code beizubehalten? [Geschlossen]


274

Welche Vor- und Nachteile hat die Beibehaltung von SQL in Ihrem C # -Quellcode oder in gespeicherten Prozessen? Ich habe dies mit einem Freund in einem Open-Source-Projekt besprochen, an dem wir arbeiten (C # ASP.NET-Forum). Derzeit erfolgt der größte Teil des Datenbankzugriffs durch Erstellen der SQL-Inline in C # und Aufrufen der SQL Server-Datenbank. Also versuche ich herauszufinden, welches für dieses spezielle Projekt am besten geeignet ist.

Bisher habe ich:

Vorteile für in Code:

  • Einfacher zu warten - Sie müssen kein SQL-Skript ausführen, um Abfragen zu aktualisieren
  • Einfacher auf eine andere Datenbank zu portieren - keine Prozesse zum Portieren

Vorteile für gespeicherte Prozesse:

  • Performance
  • Sicherheit

50
Sie könnten auch argumentieren, dass gespeicherte Prozesse die Wartung vereinfachen - Sie müssen nicht die gesamte Anwendung erneut bereitstellen, nur um eine Abfrage zu ändern.
Darren Gosbell

27
@GvS: Das ist eine Funktionsstörung Ihres Unternehmens, keine bewährte Methode. Natürlich ist es einfacher, Dinge an einem Ort als 1000 zu ändern. Die Datenbankadministratoren leisten einfach ihren Beitrag, um unbekümmerte Änderungen am System zu verhindern, und das sollte beachtet werden.
Jeremy Holovacs

Antworten:


179

Ich bin kein Fan von gespeicherten Prozeduren

Gespeicherte Prozeduren können aus folgenden Gründen besser gewartet werden: * Sie müssen Ihre C # -App nicht neu kompilieren, wenn Sie SQL ändern möchten

Sie werden es ohnehin neu kompilieren, wenn sich die Datentypen ändern oder wenn Sie eine zusätzliche Spalte oder was auch immer zurückgeben möchten. Die Häufigkeit, mit der Sie das SQL unter Ihrer App "transparent" ändern können, ist insgesamt recht gering

  • Am Ende wird SQL-Code wiederverwendet.

Programmiersprachen, einschließlich C #, haben diese erstaunliche Sache, die als Funktion bezeichnet wird. Dies bedeutet, dass Sie denselben Codeblock von mehreren Stellen aus aufrufen können! Tolle! Sie können dann den wiederverwendbaren SQL-Code in einen dieser Codes einfügen, oder wenn Sie wirklich High-Tech erhalten möchten, können Sie eine Bibliothek verwenden, die dies für Sie erledigt. Ich glaube, sie heißen Object Relational Mappers und sind heutzutage ziemlich verbreitet.

Code-Wiederholung ist das Schlimmste, was Sie tun können, wenn Sie versuchen, eine wartbare Anwendung zu erstellen!

Einverstanden, weshalb gespeicherte Prozesse eine schlechte Sache sind. Es ist viel einfacher, Code in Funktionen umzugestalten und zu zerlegen (in kleinere Teile zu zerlegen) als SQL in ... SQL-Blöcke?

Sie haben 4 Webserver und eine Reihe von Windows-Apps, die denselben SQL-Code verwenden. Jetzt haben Sie festgestellt, dass es ein kleines Problem mit dem SQl-Code gibt. Ändern Sie also lieber den Prozess an einer Stelle oder senden Sie den Code an alle Installieren Sie auf den Webservern alle Desktop-Apps (Clickonce kann hilfreich sein) auf allen Windows-Boxen neu

Warum stellen Ihre Windows-Apps eine direkte Verbindung zu einer zentralen Datenbank her? Das scheint genau dort eine RIESIGE Sicherheitslücke und ein Engpass zu sein, da es das serverseitige Caching ausschließt. Sollten sie nicht über einen Webservice oder ähnlich wie Ihre Webserver eine Verbindung herstellen?

Also 1 neuen Sproc oder 4 neue Webserver schieben?

In diesem Fall ist es ist einfacher , eine neue sproc zu schieben, aber nach meiner Erfahrung, 95% der ‚gedrückt Änderungen‘ beeinflusst den Code und nicht die Datenbank. Wenn Sie in diesem Monat 20 Dinge an die Webserver und 1 an die Datenbank senden, verlieren Sie kaum viel, wenn Sie stattdessen 21 Dinge an die Webserver und null an die Datenbank senden.

Einfacher Code überprüft.

Können Sie erklären, wie? Ich verstehe das nicht. Insbesondere, da die Sprocs wahrscheinlich nicht in der Quellcodeverwaltung sind und daher nicht über webbasierte SCM-Browser usw. aufgerufen werden können.

Weitere Nachteile:

Gespeicherte Prozesse befinden sich in der Datenbank, die der Außenwelt als Black Box angezeigt wird. Einfache Dinge wie der Wunsch, sie in die Quellcodeverwaltung zu bringen, werden zum Albtraum.

Es gibt auch das Problem der bloßen Anstrengung. Es mag sinnvoll sein, alles in eine Million Ebenen aufzuteilen, wenn Sie versuchen, Ihrem CEO zu rechtfertigen, warum es nur 7 Millionen Dollar gekostet hat, einige Foren zu erstellen, aber ansonsten ist das Erstellen eines gespeicherten Prozesses für jede Kleinigkeit nur zusätzliche Eselarbeit für Nein Vorteil.


99

Dies wird derzeit in einigen anderen Themen diskutiert. Ich bin ein konsequenter Befürworter gespeicherter Prozeduren, obwohl einige gute Argumente für Linq to Sql vorgestellt werden.

Durch das Einbetten von Abfragen in Ihren Code werden Sie eng mit Ihrem Datenmodell verbunden. Gespeicherte Prozeduren sind eine gute Form der vertraglichen Programmierung, dh ein DBA hat die Freiheit, das Datenmodell und den Code in der Prozedur zu ändern, solange der Vertrag, der durch die Ein- und Ausgaben der gespeicherten Prozedur dargestellt wird, beibehalten wird.

Das Optimieren von Produktionsdatenbanken kann äußerst schwierig sein, wenn die Abfragen im Code und nicht an einem zentralen, einfach zu verwaltenden Speicherort vergraben sind.

[Bearbeiten] Hier ist eine andere aktuelle Diskussion


47

Meiner Meinung nach können Sie bei dieser Frage nicht mit Ja oder Nein stimmen. Es hängt ganz vom Design Ihrer Anwendung ab.

Ich stimme voll und ganz gegen die Verwendung von SPs in einer dreistufigen Umgebung, in der Sie einen Anwendungsserver vor sich haben. In einer solchen Umgebung ist Ihr Anwendungsserver dazu da, Ihre Geschäftslogik auszuführen. Wenn Sie zusätzlich SPs verwenden, verteilen Sie Ihre Implementierung der Geschäftslogik auf Ihr gesamtes System, und es wird sehr unklar, wer für was verantwortlich ist. Schließlich erhalten Sie einen Anwendungsserver, der im Grunde nichts anderes als Folgendes tut:

(Pseudocode)

Function createOrder(Order yourOrder) 
Begin
  Call SP_createOrder(yourOrder)
End

Am Ende läuft also Ihre mittlere Schicht auf diesem sehr coolen 4-Server-Cluster, von denen jeder mit 16 CPUs ausgestattet ist, und er wird eigentlich gar nichts bewirken! Was für eine Verschwendung!

Wenn Sie einen fetten GUI-Client haben, der sich direkt mit Ihrer Datenbank oder vielleicht noch mehr Anwendungen verbindet, ist das eine andere Geschichte. In dieser Situation können SPs als eine Art Pseudo-Middle-Tier dienen, die Ihre Anwendung vom Datenmodell entkoppelt und einen steuerbaren Zugriff bietet.


44

Vorteile für in Code:

  • Einfacher zu warten - Sie müssen kein SQL-Skript ausführen, um Abfragen zu aktualisieren
  • Einfacher auf eine andere Datenbank zu portieren - keine Prozesse zum Portieren

Eigentlich denke ich, dass Sie das rückwärts haben. IMHO, SQL im Code ist schmerzhaft zu pflegen, weil:

  • Am Ende wiederholen Sie sich in verwandten Codeblöcken
  • SQL wird in vielen IDEs nicht als Sprache unterstützt, sodass Sie nur eine Reihe fehlerfrei überprüfter Zeichenfolgen haben, die Aufgaben für Sie ausführen
  • Änderungen an einem Datentyp, einem Tabellennamen oder einer Einschränkung sind weitaus häufiger als das Austauschen einer gesamten Datenbank gegen eine neue
  • Ihr Schwierigkeitsgrad steigt mit zunehmender Komplexität Ihrer Abfrage
  • Zum Testen einer Inline-Abfrage muss das Projekt erstellt werden

Stellen Sie sich gespeicherte Prozesse als Methoden vor, die Sie vom Datenbankobjekt aus aufrufen. Sie sind viel einfacher wiederzuverwenden, es gibt nur einen Ort zum Bearbeiten. Wenn Sie den DB-Anbieter wechseln, werden die Änderungen in Ihren gespeicherten Prozessen und nicht in Ihrem Code vorgenommen .

Das heißt, der Leistungsgewinn von gespeicherten Prozessen ist minimal, wie Stu vor mir sagte, und Sie können (noch) keinen Haltepunkt in eine gespeicherte Prozedur setzen.


33

CON

Ich finde, dass eine Menge Verarbeitung in gespeicherten Prozeduren Ihren DB-Server zu einem einzigen Punkt der Inflexibilität machen würde, wenn es darum geht, Ihre Handlung zu skalieren.

Wenn Sie jedoch all das Knirschen in Ihrem Programm im Gegensatz zum SQL-Server ausführen, können Sie möglicherweise mehr skalieren, wenn Sie mehrere Server haben, auf denen Ihr Code ausgeführt wird. Dies gilt natürlich nicht für gespeicherte Prozesse, die nur das normale Abrufen oder Aktualisieren durchführen, sondern für solche, die mehr Verarbeitung ausführen, z. B. das Durchlaufen von Datensätzen.

PROS

  1. Leistung für das, was es wert sein mag (vermeidet das Parsen von Abfragen durch DB-Treiber / Plan-Neuerstellung usw.)
  2. Die Datenmanipulation ist nicht in den C / C ++ / C # -Code eingebettet, was bedeutet, dass ich weniger Code auf niedriger Ebene durchsehen muss. SQL ist weniger ausführlich und einfacher zu durchschauen, wenn es separat aufgeführt wird.
  3. Aufgrund der Trennung können Leute SQL-Code viel einfacher finden und wiederverwenden.
  4. Es ist einfacher, Dinge zu ändern, wenn sich das Schema ändert - Sie müssen dem Code nur die gleiche Ausgabe geben, und es funktioniert einwandfrei
  5. Einfachere Portierung auf eine andere Datenbank.
  6. Ich kann einzelne Berechtigungen für meine gespeicherten Prozeduren auflisten und den Zugriff auch auf dieser Ebene steuern.
  7. Ich kann meinen Datenabfrage- / Persistenzcode getrennt von meinem Datentransformationscode profilieren.
  8. Ich kann veränderbare Bedingungen in meine gespeicherte Prozedur implementieren und es wäre einfach, sie beim Kunden anzupassen.
  9. Es wird einfacher, einige automatisierte Tools zu verwenden, um mein Schema und meine Anweisungen zusammen zu konvertieren, als wenn es in meinen Code eingebettet ist, wo ich sie suchen müsste.
  10. Das Sicherstellen von Best Practices für den Datenzugriff ist einfacher, wenn Sie Ihren gesamten Datenzugriffscode in einer einzigen Datei haben. Ich kann nach Abfragen suchen, die auf die nicht performante Tabelle zugreifen oder die einen höheren Serialisierungsgrad verwenden, oder * im Code usw. Auswählen .
  11. Es wird einfacher, Schemaänderungen / Änderungen der Datenmanipulationslogik zu finden, wenn alles in einer Datei aufgelistet ist.
  12. Es wird einfacher, Änderungen in SQL zu suchen und zu ersetzen, wenn sie sich an derselben Stelle befinden, z. B. Transaktionsisolationsanweisungen für alle gespeicherten Prozesse ändern / hinzufügen.
  13. Ich und der DBA-Typ finden, dass es einfacher / bequemer ist, eine separate SQL-Datei zu haben, wenn der DBA meine SQL-Daten überprüfen muss.
  14. Schließlich müssen Sie sich keine Gedanken über SQL-Injection-Angriffe machen, da einige faule Mitglieder Ihres Teams bei der Verwendung eingebetteter SQL-Dateien keine parametrisierten Abfragen verwendet haben.

22

Der Leistungsvorteil für gespeicherte Prozeduren ist häufig vernachlässigbar.

Weitere Vorteile für gespeicherte Prozeduren:

  • Verhindern Sie Reverse Engineering (falls mit Verschlüsselung erstellt, natürlich)
  • Bessere Zentralisierung des Datenbankzugriffs
  • Möglichkeit, das Datenmodell transparent zu ändern (ohne neue Clients bereitstellen zu müssen); Besonders praktisch, wenn mehrere Programme auf dasselbe Datenmodell zugreifen

16

Ich falle auf die Codeseite . Wir erstellen eine Datenzugriffsschicht, die von allen Apps (sowohl Web als auch Client) verwendet wird, sodass sie aus dieser Perspektive trocken ist. Dies vereinfacht die Datenbankbereitstellung, da nur sichergestellt werden muss, dass die Tabellenschemata korrekt sind. Dies vereinfacht die Codepflege, da wir uns nicht mit dem Quellcode und der Datenbank befassen müssen.

Ich habe kein großes Problem mit der engen Kopplung mit dem Datenmodell, weil ich nicht sehe, wo es möglich ist, diese Kopplung wirklich zu brechen. Eine Anwendung und ihre Daten sind inhärent gekoppelt.


13

Gespeicherte Prozeduren.

Wenn ein Fehler auftritt oder sich die Logik ein wenig ändert, müssen Sie das Projekt nicht neu kompilieren. Außerdem können Sie von verschiedenen Quellen aus zugreifen, nicht nur von der Stelle, an der Sie die Abfrage in Ihrem Projekt codiert haben.

Ich denke nicht, dass es schwieriger ist, gespeicherte Prozeduren zu verwalten. Sie sollten sie nicht direkt in der Datenbank codieren, sondern zuerst in separaten Dateien. Dann können Sie sie einfach auf der Datenbank ausführen, die Sie einrichten müssen.


24
Wenn Sie grundlegende architektonische Entscheidungen treffen, um ein erneutes Kompilieren Ihres Codes zu vermeiden, sollten Sie vor dem Ausführen eines Vorgangs einen Erstellungsprozess einrichten, der nicht völlig zum Kotzen ist. Dies ist kein Argument.
Michael Borgwardt

13

Vorteile für gespeicherte Prozeduren :

Einfacher Code überprüft.

Weniger gekoppelt, daher leichter zu testen.

Einfacher einzustellen.

Die Leistung ist im Hinblick auf den Netzwerkverkehr im Allgemeinen besser. Wenn Sie einen Cursor oder ähnliches haben, gibt es nicht mehrere Fahrten zur Datenbank

Sie können den Zugriff auf die Daten einfacher schützen, den direkten Zugriff auf die Tabellen entfernen und die Sicherheit durch die Prozesse erzwingen. Auf diese Weise können Sie auch relativ schnell Code finden, der eine Tabelle aktualisiert.

Wenn andere Dienste beteiligt sind (z. B. Berichtsdienste), ist es möglicherweise einfacher, Ihre gesamte Logik in einer gespeicherten Prozedur als in Code zu speichern und sie zu duplizieren

Nachteile:

Für die Entwickler schwieriger zu verwalten: Versionskontrolle der Skripte: Hat jeder seine eigene Datenbank? Ist das Versionskontrollsystem in die Datenbank und die IDE integriert?


Ja, Sie können eine Versionskontrolle in gespeicherten Prozeduren und Datenbanken in Visual Studio 2012-Datenbankprojekten und tfs durchführen.
Hajirazin

11

Unter bestimmten Umständen kann dynamisch erstellter SQL-Code eine bessere Leistung aufweisen als ein gespeicherter Prozess. Wenn Sie einen gespeicherten Prozess erstellt haben (sagen wir sp_customersearch), der mit Dutzenden von Parametern extrem kompliziert wird, weil er sehr flexibel sein muss, können Sie zur Laufzeit wahrscheinlich eine viel einfachere SQL-Anweisung im Code generieren.

Man könnte argumentieren, dass dies einfach eine Verarbeitung von SQL auf den Webserver verlagert, aber im Allgemeinen wäre das eine gute Sache.

Das andere gute an dieser Technik ist, dass Sie im SQL-Profiler die von Ihnen generierte Abfrage sehen und viel einfacher debuggen können, als wenn ein gespeicherter Proc-Aufruf mit 20 Parametern eingeht.


1
Ich bin mir nicht sicher, warum diese Antwort abgelehnt wurde. Es stimmt, dass eine kleinere Abfrage eine bessere Leistung erzielen kann. Dies wurde sogar vom SQL Server-Team kommentiert.
Brannon

9

Ich mag gespeicherte Prozesse, weiß nicht, wie oft ich eine Anwendung mit einer gespeicherten Prozedur ändern konnte, die keine Ausfallzeiten für die Anwendung verursachte.

Ein großer Fan von Transact SQL, das Optimieren großer Abfragen hat sich für mich als sehr nützlich erwiesen. Ich habe seit ungefähr 6 Jahren kein Inline-SQL mehr geschrieben!


Ich kann einen anderen Standpunkt unter Verwendung von Abfragen im Code einfach nicht verstehen, kann einfach nicht verstehen ...
Chaki_Black

8

Sie listen 2 Pro-Punkte für Sprocs auf:

Leistung - nicht wirklich. In SQL 2000 oder höher sind die Abfrageplanoptimierungen ziemlich gut und werden zwischengespeichert. Ich bin sicher, dass Oracle usw. ähnliche Dinge tun. Ich glaube nicht, dass es mehr Gründe für Leistung gibt.

Sicherheit? Warum sollten Sprocs sicherer sein? Sofern Sie nicht über eine ziemlich ungesicherte Datenbank verfügen, erfolgt der gesamte Zugriff über Ihre Datenbankadministratoren oder über Ihre Anwendung. Parametrisieren Sie immer alle Abfragen - fügen Sie niemals etwas aus Benutzereingaben ein, und alles wird gut.

Das ist sowieso die beste Vorgehensweise für die Leistung.

Linq ist definitiv der Weg, den ich gerade für ein neues Projekt gehen würde. Siehe diesen ähnlichen Beitrag .


Ad-hoc-SQL-Ausführungspläne werden nur unter bestimmten Umständen wiederverwendet: tinyurl.com/6x5lmd [SO-Antwort mit Code-Beweis] LINQ to SQL ist offiziell tot: tinyurl.com/6298nd [Blog-Beitrag]
HTTP 410

1
Procs sind bei weitem der sicherste Weg. Sie hindern den Benutzer daran, nur die Aktionen in den Prozessen auszuführen. Sie können nicht direkt zu einer Tabelle oder Ansicht gehen, auf die sie Schreibzugriff haben, und Dinge ändern. Prozesse sind erforderlich, um Schäden durch interne Bedrohungen zu verhindern.
HLGEM

8

@ Keith

Sicherheit? Warum sollten Sprocs sicherer sein?

Wie von Komradekatz vorgeschlagen, können Sie den Zugriff auf Tabellen (für die Kombination aus Benutzername und Kennwort, die eine Verbindung zur Datenbank herstellt) nicht zulassen und nur den SP-Zugriff zulassen. Auf diese Weise kann jemand, der den Benutzernamen und das Kennwort für Ihre Datenbank erhält, SPs ausführen, jedoch nicht auf die Tabellen oder einen anderen Teil der Datenbank zugreifen.

(Natürlich können sie beim Ausführen von Sprocs alle benötigten Daten erhalten, dies hängt jedoch von den verfügbaren Sprocs ab. Wenn sie Zugriff auf die Tabellen erhalten, erhalten sie Zugriff auf alles.)


1
@ Joe Philllips, Ansichten geben Ihnen keine bessere oder sogar gleiche Sicherheit für Procs und sie sind NICHT nützlich, um Betrug oder internen Schaden zu verhindern. Wenn Sie procs verwenden, besteht das Sicherheitsmodell darin, dass die Benutzer nur auf den proc zugreifen, nicht auf die Tabellen oder Ansichten, und daher nur das tun können, was ein proc tut. Wenn Sie über Finanzdaten verfügen und keine Procs verwenden, ist Ihr System gefährdet.
HLGEM

7

Denk darüber so

Sie haben 4 Webserver und eine Reihe von Windows-Apps, die denselben SQL-Code verwenden. Jetzt haben Sie festgestellt, dass es ein kleines Problem mit dem SQl-Code gibt. Ändern Sie also lieber den Prozess an einer Stelle oder senden Sie den Code an alle Installieren Sie auf den Webservern alle Desktop-Apps (Clickonce kann hilfreich sein) auf allen Windows-Boxen neu

Ich bevorzuge gespeicherte Prozesse

Es ist auch einfacher, Leistungstests für einen Prozess durchzuführen, indem Sie ihn in den Abfrageanalysator setzen. Setzen Sie die Statistik io / time auf set showplan_text on und voila

Sie müssen den Profiler nicht ausführen, um genau zu sehen, wie er aufgerufen wird

nur meine 2 Cent


6

Ich bevorzuge es, sie im Code zu speichern (mit einem ORM, nicht inline oder ad-hoc), damit sie von der Quellcodeverwaltung abgedeckt werden, ohne dass das Speichern von SQL-Dateien erforderlich ist.

Außerdem sind gespeicherte Prozeduren von Natur aus nicht sicherer. Sie können eine fehlerhafte Abfrage mit einem Sproc genauso einfach schreiben wie inline. Parametrisierte Inline-Abfragen können genauso sicher sein wie ein Sproc.


6

Verwenden Sie Ihren App-Code als das, was er am besten kann: Umgang mit Logik.
Verwenden Sie Ihre Datenbank für das, was sie am besten kann: Daten speichern.

Sie können gespeicherte Prozeduren debuggen, aber das Debuggen und Verwalten der Logik im Code ist einfacher. Normalerweise beenden Sie die Neukompilierung Ihres Codes jedes Mal, wenn Sie das Datenbankmodell ändern.

Auch gespeicherte Prozeduren mit optionalen Suchparametern sind sehr unzulänglich, da Sie alle möglichen Parameter im Voraus angeben müssen und komplexe Suchvorgänge manchmal nicht möglich sind, da Sie nicht vorhersagen können, wie oft ein Parameter in der Suche wiederholt wird.


2
Wenn mehrere Apps auf dieselbe Datenbank zugreifen und Datenbanken von Importen und anderen direkten Zugriffen betroffen sind (aktualisieren Sie alle Preise um 10%), muss sich die Logik in der Datenbank befinden. Andernfalls verlieren Sie die Datenbankintegrität.
HLGEM

Bei mehreren Apps ermöglicht das Platzieren der Logik in einer Bibliothek, die von allen Apps verwendet wird, die Aufrechterhaltung der Integrität, während die Logik weiterhin in der App-Sprache bleibt. Bei Importen / Direktzugriffen ist es im Allgemeinen situativ, ob die für Apps geltenden Regeln durchgesetzt werden sollen oder nicht.
Dave Sherohman

3
Mehrere Apps sollten nicht die gleichen Änderungen an der Datenbank vornehmen. Es sollte eine App-Komponente geben, die sich mit einer einzelnen Art von Änderungen befasst. Dann sollte diese App einen Dienst verfügbar machen, wenn andere interessiert sind. Mehrere Apps, die dieselbe Datenbank / Tabelle nach eigenem Ermessen ändern, führen dazu, dass ein System von Apps und die Datenbank nicht mehr gewartet werden können.
Jiho Han

2
"Es sollte eine App-Komponente geben, die sich mit einer einzelnen Art von Änderungen befasst" - Diese Komponente könnte eine gespeicherte Prozedur sein, beispielsweise in PL / SQL.
RussellH

6

Wenn es um Sicherheit geht, sind gespeicherte Prozeduren viel sicherer. Einige haben argumentiert, dass der gesamte Zugriff ohnehin über die Anwendung erfolgen wird. Viele Menschen vergessen, dass die meisten Sicherheitsverletzungen innerhalb eines Unternehmens auftreten. Überlegen Sie, wie viele Entwickler den "versteckten" Benutzernamen und das Kennwort für Ihre Anwendung kennen?

Wie MatthieuF betonte, kann die Leistung durch weniger Roundtrips zwischen der Anwendung (egal ob auf einem Desktop- oder Webserver) und dem Datenbankserver erheblich verbessert werden.

Nach meiner Erfahrung verbessert die Abstraktion des Datenmodells durch gespeicherte Prozeduren auch die Wartbarkeit erheblich. Als jemand, der in der Vergangenheit viele Datenbanken pflegen musste, ist es eine große Erleichterung, wenn er mit einer erforderlichen Modelländerung konfrontiert wird, einfach ein oder zwei gespeicherte Prozeduren ändern zu können und die Änderung für ALLE externen Anwendungen vollständig transparent zu machen. Oft ist Ihre Anwendung nicht die einzige, auf die in einer Datenbank verwiesen wird - es gibt andere Anwendungen, Berichtslösungen usw., sodass das Aufspüren aller betroffenen Punkte beim offenen Zugriff auf die Tabellen problematisch sein kann.

Ich werde auch die Plus-Spalte überprüfen, um die SQL-Programmierung in die Hände derjenigen zu legen, die sich darauf spezialisiert haben, und für SPs, die das Isolieren und Testen / Optimieren von Code erheblich vereinfachen.

Der einzige Nachteil, den ich sehe, ist, dass viele Sprachen die Übergabe von Tabellenparametern nicht zulassen. Daher kann die Übergabe von Datenwerten mit unbekannter Nummer ärgerlich sein, und einige Sprachen können immer noch nicht mehrere Ergebnismengen von einer einzelnen gespeicherten Prozedur abrufen (obwohl die Letzteres macht SPs in dieser Hinsicht nicht schlechter als Inline-SQL.


Wenn sich das Modell ändert, muss sich normalerweise auch der Code ändern, unabhängig davon, ob Sprocs oder dynamisches SQL verwendet werden. Und wenn Sie einmal Tabellen / Schemas erstellt haben, wie oft ändern Sie nur die Tabelle / das Schema? Nicht oft. Normalerweise kommen Änderungen aus dem Geschäft, wo sie eine weitere Spalte oder eine andere Tabelle hinzufügen müssen. In diesem Fall bezweifle ich, dass Sie auf eine Codeänderung verzichten können.
Jiho Han

4

Einer der Vorschläge aus einer Microsoft TechEd-Sitzung zum Thema Sicherheit, an der ich teilgenommen habe, alle Anrufe über gespeicherte Prozesse zu tätigen und den direkten Zugriff auf die Tabellen zu verweigern. Dieser Ansatz wurde als zusätzliche Sicherheit in Rechnung gestellt. Ich bin mir nicht sicher, ob es sich nur aus Sicherheitsgründen lohnt, aber wenn Sie bereits gespeicherte Prozesse verwenden, kann dies nicht schaden.


Datensicherheit ist wichtig, wenn Sie sich mit persönlichen Informationen oder finanziellen Informationen beschäftigen. Der meiste Betrug wird von Insidern begangen. Sie möchten ihnen nicht den Zugriff gewähren, den sie benötigen, um interne Kontrollen zu umgehen.
HLGEM

4

Auf jeden Fall einfacher zu warten, wenn Sie es in eine gespeicherte Prozedur legen. Wenn es sich um eine schwierige Logik handelt, die sich möglicherweise in Zukunft ändern wird, ist es auf jeden Fall eine gute Idee, sie in die Datenbank aufzunehmen, wenn mehrere Clients eine Verbindung herstellen. Zum Beispiel arbeite ich gerade an einer Anwendung mit einer Endbenutzer-Weboberfläche und einer administrativen Desktop-Anwendung, die beide (offensichtlich) eine Datenbank gemeinsam nutzen, und ich versuche, so viel Logik wie möglich in der Datenbank zu behalten. Dies ist ein perfektes Beispiel für das DRY-Prinzip .


4

Ich bin fest auf der Seite der gespeicherten Prozesse, vorausgesetzt, Sie betrügen nicht und verwenden dynamisches SQL im gespeicherten Prozess. Erstens ermöglicht die Verwendung gespeicherter Prozesse der Datenbank, Berechtigungen auf der Ebene der gespeicherten Prozesse und nicht auf der Tabellenebene festzulegen. Dies ist nicht nur wichtig, um SQL-Injection-Attacken zu bekämpfen, sondern auch, um zu verhindern, dass Insider direkt auf die Datenbank zugreifen und Änderungen vornehmen. Dies ist ein Weg, um Betrug zu verhindern. Auf keine Datenbank, die persönliche Informationen enthält (SSNs, Kreditkartennummern usw.) oder die ohnehin Finanztransaktionen erstellt, sollte jemals zugegriffen werden, außer durch strenge Verfahren. Wenn Sie eine andere Methode verwenden, lassen Sie Ihre Datenbank für Einzelpersonen im Unternehmen offen, um gefälschte Finanztransaktionen zu erstellen oder Daten zu stehlen, die für Identitätsdiebstahl verwendet werden können.

Gespeicherte Prozesse sind außerdem viel einfacher zu warten und die Leistung zu optimieren als SQL, das von der App gesendet wird. Sie ermöglichen der Datenbank auch zu sehen, welche Auswirkungen eine Datenbankstrukturänderung auf die Art und Weise hat, wie auf die Daten zugegriffen wird. Ich habe noch nie eine gute Datenbank getroffen, die einen dynamischen Zugriff auf die Datenbank ermöglichen würde.


4

Wir verwenden gespeicherte Prozeduren mit Oracle-DBs, in denen ich jetzt arbeite. Wir verwenden auch Subversion. Alle gespeicherten Prozeduren werden als .pkb- und .pks-Dateien erstellt und in Subversion gespeichert. Ich habe schon einmal Inline-SQL gemacht und es ist ein Schmerz! Ich bevorzuge die Art und Weise, wie wir es hier machen. Das Erstellen und Testen neuer gespeicherter Prozeduren ist viel einfacher als das Erstellen in Ihrem Code.

Da ist ein


3

Kleinere Protokolle

Ein weiterer kleiner Vorteil für gespeicherte Prozeduren, der nicht erwähnt wurde: Wenn es um SQL-Verkehr geht, generiert der sp-basierte Datenzugriff viel weniger Verkehr. Dies ist wichtig, wenn Sie den Datenverkehr auf Analyse und Profilerstellung überwachen. Die Protokolle sind viel kleiner und lesbar.


3

Ich bin kein großer Fan von gespeicherten Prozeduren, aber ich verwende sie unter einer Bedingung:

Wenn die Abfrage ziemlich groß ist, ist es besser, sie als gespeicherte Prozedur in der Datenbank zu speichern, als sie aus dem Code zu senden. Auf diese Weise werden nicht nur große Mengen von Zeichenfolgen vom Anwendungsserver an die Datenbank gesendet, sondern nur die"EXEC SPNAME" Befehl gesendet zu senden.

Dies ist zu viel des Guten, wenn sich der Datenbankserver und der Webserver nicht im selben Netzwerk befinden (z. B. Internetkommunikation). Und selbst wenn dies nicht der Fall ist, bedeutet zu viel Stress viel verschwendete Bandbreite.

Aber Mann, es ist so schrecklich, sie zu verwalten. Ich vermeide sie so weit ich kann.


3

Ein gespeicherter SQL-Prozess erhöht die Leistung der Abfrage nicht


Wie kann es nicht sein? Bitte erläutern Sie dies.
Sandesh

Dies erhöht die Leistung, wenn die SQL-Abfrage kompiliert werden kann.
TT.

3

Die Verwendung gespeicherter Prozeduren hat offensichtlich mehrere Vorteile gegenüber der Erstellung von SQL im Code.

  1. Ihre Code-Implementierung und SQL werden unabhängig voneinander.
  2. Code ist leichter zu lesen.
  3. Einmal schreiben, mehrmals verwenden.
  4. Einmal ändern
  5. Sie müssen dem Programmierer keine internen Details zur Datenbank mitteilen. usw. usw.

Ich war noch nie in einer Situation, in der es für mich von Vorteil war, weniger Informationen über ein Codeproblem oder eine neue Funktion zu haben. Können Sie Nummer 5 klarstellen?
OpenCoderX

2

Stored Procedures sind MEHR wartbar , weil:

  • Sie müssen Ihre C # -App nicht neu kompilieren, wenn Sie SQL ändern möchten
  • Am Ende wird SQL-Code wiederverwendet.

Code-Wiederholung ist das Schlimmste, was Sie tun können, wenn Sie versuchen, eine wartbare Anwendung zu erstellen!

Was passiert, wenn Sie einen logischen Fehler finden, der an mehreren Stellen korrigiert werden muss? Sie vergessen eher, die letzte Stelle zu ändern, an der Sie Ihren Code kopiert und eingefügt haben.

Meiner Meinung nach sind die Leistungs- und Sicherheitsgewinne ein zusätzliches Plus. Sie können weiterhin unsichere / ineffiziente gespeicherte SQL-Prozeduren schreiben.

Einfacher auf eine andere Datenbank zu portieren - keine Prozesse zum Portieren

Es ist nicht sehr schwer, alle Ihre gespeicherten Prozeduren für die Erstellung in einer anderen Datenbank zu skripten. In der Tat - es ist einfacher als das Exportieren Ihrer Tabellen, da es keine Primär- / Fremdschlüssel gibt, über die Sie sich Sorgen machen müssen.


Nur ein Hinweis: "Einfacher auf eine andere Datenbank zu portieren - keine Prozesse auf Port" bezieht sich auf die Portierung auf ein anderes DBMS , nicht nur auf eine andere Installation. Es gibt Alternativen da draußen, weißt du ;-).
Sleske

2

@ Terrapin - Sprocs sind genauso anfällig für Injektionsangriffe. Wie ich sagte:

Parametrisieren Sie immer alle Abfragen - fügen Sie niemals etwas aus Benutzereingaben ein, und alles wird gut.

Das gilt für Sprocs und dynamische SQL.

Ich bin mir nicht sicher, ob es von Vorteil ist, Ihre App nicht neu zu kompilieren. Ich meine, Sie haben Ihre Unit-Tests mit diesem Code (sowohl Anwendung als auch DB) durchgeführt, bevor Sie trotzdem wieder live gehen.


@Guy - Ja, Sie haben Recht. Mit Sprocs können Sie Anwendungsbenutzer so steuern, dass sie nur den Sproc ausführen können, nicht die zugrunde liegende Aktion.

Meine Frage wäre: Wenn der gesamte Zugriff über Ihre App über Verbindungen und Benutzer mit eingeschränkten Rechten zum Aktualisieren / Einfügen usw. erfolgt, erhöht diese zusätzliche Ebene die Sicherheit oder die zusätzliche Verwaltung?

Meine Meinung ist sehr viel Letzteres. Wenn sie Ihre Anwendung bis zu dem Punkt kompromittiert haben, an dem sie sie neu schreiben können, haben sie viele andere Angriffe, die sie verwenden können.

SQL-Injektionen können weiterhin für diese Sprocs ausgeführt werden, wenn sie dynamisch Inline-Code enthalten. Daher gilt weiterhin die goldene Regel. Alle Benutzereingaben müssen immer parametrisiert werden.


Es sind nicht nur Angriffe von außen, gegen die man kämpfen muss. Sie können Benutzern keinen direkten Zugriff auf die Tabellen gewähren, die dann die Daten ändern könnten, um Betrug zu begehen.
HLGEM

Als Richtlinie sollte es gespeicherten Prozessen nicht gestattet sein, dynamisches SQL zu verwenden. Es gibt fast immer eine nicht dynamische Lösung, wenn Sie danach suchen.
HLGEM

Die SQL-Injection ist bei Sprocs mit dynamisch inlineem Code nicht so effektiv, da dynamischer Code mit Aufruferberechtigung und nicht mit Eigentümerberechtigung ausgeführt wird (im Gegensatz zu statischem Code). Dies gilt für SQL Server - bei Oracle nicht sicher.
HTTP 410

2

Etwas, das ich bisher noch nicht gesehen habe: Die Leute, die die Datenbank am besten kennen, sind nicht immer die Leute, die den Anwendungscode schreiben. Gespeicherte Prozeduren bieten den Datenbankleuten die Möglichkeit, mit Programmierern zusammenzuarbeiten, die nicht wirklich so viel über SQL lernen möchten. Große - und insbesondere ältere - Datenbanken sind nicht so einfach zu verstehen, daher bevorzugen Programmierer möglicherweise eine einfache Oberfläche, die ihnen das bietet, was sie benötigen: Lassen Sie die Datenbankadministratoren herausfinden, wie sie die 17 Tabellen verbinden, um dies zu erreichen.

Abgesehen davon sind die Sprachen, die zum Schreiben gespeicherter Prozeduren verwendet werden (PL / SQL ist ein berüchtigtes Beispiel), ziemlich brutal. Sie bieten normalerweise keine der Feinheiten, die Sie in den heutigen populären Imperativ-, OOP- oder Funktionssprachen sehen würden. Denken Sie an COBOL.

Halten Sie sich also an gespeicherte Prozeduren, die lediglich die relationalen Details abstrahieren, anstatt diejenigen, die Geschäftslogik enthalten.


"Die Sprachen, die zum Schreiben gespeicherter Prozeduren verwendet werden (PL / SQL ist ein berüchtigtes Beispiel), sind ziemlich brutal [und] bieten keine der Feinheiten, die Sie in den heutigen populären Sprachen sehen würden." Sie müssen die PL / SQL-Dokumente erneut lesen ( download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/toc.htm ). PL / SQL verfügt über eine Kapselung mithilfe von Paketen, OOP über Objekttypen, Ausnahmebehandlung, dynamische Ausführung von Code, Debuggern, Profilern usw. sowie Hunderte von Standardpaketen / -bibliotheken, die von Oracle bereitgestellt werden, um alles von HTTP-Aufrufen über Verschlüsselung bis hin zu regulären Ausdrücken zu erledigen . PL / SQL hat viele Feinheiten.
ObiWanKenobi

2

Ich schreibe normalerweise OO-Code. Ich vermute, dass die meisten von Ihnen das wahrscheinlich auch tun. In diesem Zusammenhang scheint mir offensichtlich, dass die gesamte Geschäftslogik - einschließlich SQL-Abfragen - in die Klassendefinitionen gehört. Es ist nicht besser, die Logik so aufzuteilen, dass sich ein Teil davon im Objektmodell und ein Teil in der Datenbank befindet, als Geschäftslogik in die Benutzeroberfläche einzufügen.

In früheren Antworten wurde viel über die Sicherheitsvorteile gespeicherter Prozesse gesagt. Diese fallen in zwei große Kategorien:

1) Einschränkung des direkten Zugriffs auf die Daten. Dies ist in einigen Fällen definitiv wichtig, und wenn Sie auf einen stoßen, sind gespeicherte Prozesse so ziemlich Ihre einzige Option. Nach meiner Erfahrung sind solche Fälle jedoch eher die Ausnahme als die Regel.

2) SQL-Injection / parametrisierte Abfragen. Dieser Einwand ist ein roter Hering. Inline-SQL - selbst dynamisch generiertes Inline-SQL - kann genauso vollständig parametrisiert werden wie jeder gespeicherte Prozess und genauso einfach in jeder modernen Sprache ausgeführt werden, die es wert ist. Hier gibt es keinen Vorteil. ("Faule Entwickler kümmern sich möglicherweise nicht um die Verwendung von Parametern" ist kein gültiger Einwand. Wenn Sie Entwickler in Ihrem Team haben, die es vorziehen, Benutzerdaten nur in ihrem SQL zu verketten, anstatt Parameter zu verwenden, versuchen Sie zuerst, sie zu schulen, und feuern sie dann ab Wenn das nicht funktioniert, genau wie bei Entwicklern, die andere schlechte, nachweislich schädliche Angewohnheiten haben.)


2

Ich bin ein großer Befürworter von Code gegenüber SPROCs. Der Hauptgrund dafür ist, dass der Code eng gekoppelt bleibt. Eine knappe Sekunde ist die einfache Quellcodeverwaltung, ohne dass viele benutzerdefinierte Dienstprogramme zum Abrufen erforderlich sind.

Wenn wir in unserer DAL sehr komplexe SQL-Anweisungen haben, fügen wir diese im Allgemeinen als Ressourcendateien hinzu und aktualisieren sie nach Bedarf (dies kann auch eine separate Assembly sein und pro Datenbank usw. ausgetauscht werden).

Dadurch bleiben unser Code und unsere SQL-Aufrufe in derselben Versionskontrolle gespeichert, ohne zu "vergessen", einige externe Anwendungen zum Aktualisieren auszuführen.


Was ist, wenn Sie "vergessen", Änderungen an Tabellen zu replizieren?
Craigmoliver

Prozess kann Bereitstellungsprobleme lösen.
Tom Anderson
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.