Was sind die Vor- und Nachteile der Beibehaltung von SQL in Stored Procs im Vergleich zu Code [geschlossen]

StackOverflow https://stackoverflow.com/questions/15142

Frage

Welche Vor- und Nachteile hat es, SQL in Ihrem C#-Quellcode oder in Stored Procs zu behalten?Ich habe dies mit einem Freund über ein Open-Source-Projekt besprochen, an dem wir arbeiten (C# ASP.NET-Forum).Derzeit erfolgt der Großteil des Datenbankzugriffs durch die Inline-Erstellung von SQL in C# und den Aufruf der SQL Server-Datenbank.Deshalb versuche ich herauszufinden, welches für dieses spezielle Projekt das Beste wäre.

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 beim Portieren

Vorteile für gespeicherte Prozesse:

  • Leistung
  • Sicherheit
War es hilfreich?

Lösung

Ich bin kein Fan von gespeicherten Prozeduren

Gespeicherte Prozeduren sind wartbarer, weil:* Sie müssen Ihre C#-App nicht jedes Mal neu kompilieren, wenn Sie SQL ändern möchten

Sie werden es sowieso neu kompilieren, wenn sich Datentypen ändern oder Sie eine zusätzliche Spalte zurückgeben möchten oder was auch immer.Die Häufigkeit, mit der Sie die SQL-Anweisungen unterhalb Ihrer App „transparent“ ändern können, ist im Großen und Ganzen ziemlich gering

  • Am Ende verwenden Sie SQL-Code wieder.

Programmiersprachen, einschließlich C#, verfügen über dieses erstaunliche Ding, eine sogenannte Funktion.Das bedeutet, dass Sie denselben Codeblock von mehreren Stellen aus aufrufen können!Toll!Anschließend können Sie den wiederverwendbaren SQL-Code in einen dieser Codes einfügen. Wenn Sie wirklich High-Tech benötigen, können Sie eine Bibliothek verwenden, die dies für Sie erledigt.Ich glaube, sie werden Object Relational Mapper genannt und sind heutzutage ziemlich verbreitet.

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

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

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, also möchten Sie lieber …Ändern Sie den Prozess an einer Stelle oder übertragen Sie den Code auf alle Webserver. Installieren Sie alle Desktop-Apps (Clickonce könnte 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 Flaschenhals zu sein, da serverseitiges Caching ausgeschlossen ist.Sollten sie sich nicht über einen Webdienst oder ähnliches mit Ihren Webservern verbinden?

Also 1 neuen Sproc oder 4 neue Webserver pushen?

In diesem Fall Ist Es ist einfacher, einen neuen Sproc zu pushen, aber meiner Erfahrung nach wirken sich 95 % der „gepushten Änderungen“ auf den Code und nicht auf die Datenbank aus.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.

Einfachere Codeüberprüfung.

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

Weitere Nachteile:

Storedprocs leben in der Datenbank, die nach außen wie eine Blackbox erscheint.Einfache Dinge wie der Wunsch, sie in die Quellcodeverwaltung zu integrieren, werden zum Albtraum.

Es gibt auch das Problem der reinen Anstrengung.Es könnte sinnvoll sein, alles in eine zu zerlegen Millionen Stufen Wenn Sie versuchen, Ihrem CEO gegenüber zu rechtfertigen, warum es ihn nur 7 Millionen Dollar gekostet hat, ein paar Foren zu erstellen, aber ansonsten für jede Kleinigkeit einen gespeicherten Prozess zu erstellen, ist nur zusätzliche Eselarbeit ohne Nutzen.

Andere Tipps

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

Durch das Einbetten von Abfragen in Ihren Code sind Sie eng an Ihr Datenmodell gebunden.Gespeicherte Prozeduren sind eine gute Form der Vertragsprogrammierung, was bedeutet, dass ein DBA die Freiheit hat, das Datenmodell und den Code in der Prozedur zu ändern, solange der durch die Ein- und Ausgaben der gespeicherten Prozedur dargestellte Vertrag eingehalten wird.

Die Optimierung von Produktionsdatenbanken kann äußerst schwierig sein, wenn die Abfragen im Code vergraben sind und sich nicht an einem zentralen, einfach zu verwaltenden Ort befinden.

[Bearbeiten] Hier ist noch einer aktuelle Diskussion

Meiner Meinung nach kann man bei dieser Frage nicht mit Ja oder Nein stimmen.Es hängt ganz vom Design Ihrer Anwendung ab.

Ich stimme völlig gegen den Einsatz von SPs in einer 3-Tier-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 über Ihr gesamtes System und es wird sehr unklar, wer wofür verantwortlich ist.Letztendlich erhalten Sie einen Anwendungsserver, der im Grunde nur Folgendes tut:

(Pseudocode)

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

Am Ende läuft also Ihre Mittelschicht auf diesem sehr coolen 4-Server-Cluster, von denen jeder mit 16 CPUs ausgestattet ist, und es wird eigentlich überhaupt nichts tun!Was für eine Verschwendung!

Wenn Sie einen Fat-GUI-Client haben, der eine direkte Verbindung zu Ihrer Datenbank oder vielleicht sogar noch mehr Anwendungen herstellt, ist die Sache eine andere Sache.In dieser Situation können SPs als eine Art Pseudo-Mittelschicht dienen, die Ihre Anwendung vom Datenmodell entkoppelt und einen kontrollierbaren Zugriff bietet.

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 beim Portieren

Eigentlich glaube ich, dass Sie das falsch verstanden haben.Meiner Meinung nach ist die Wartung von SQL im Code mühsam, 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 von auf Fehler überprüften Zeichenfolgen haben, die Aufgaben für Sie ausführen
  • Änderungen an einem Datentyp, Tabellennamen oder einer Einschränkung sind weitaus häufiger als der Austausch einer gesamten Datenbank gegen eine neue
  • Ihr Schwierigkeitsgrad steigt mit zunehmender Komplexität Ihrer Anfrage
  • und das Testen einer Inline-Abfrage erfordert die Erstellung des Projekts

Stellen Sie sich Stored Procs als Methoden vor, die Sie vom Datenbankobjekt aus aufrufen – sie sind viel einfacher wiederzuverwenden, es gibt nur einen Ort zum Bearbeiten und für den Fall, dass Sie den DB-Anbieter wechseln, erfolgen die Änderungen in Ihren Stored Procs und nicht in Ihrem Code .

Allerdings sind die Leistungssteigerungen gespeicherter Prozesse minimal, wie Stu vor mir sagte, und Sie können (noch) keinen Haltepunkt in eine gespeicherte Prozedur einfügen.

CON

Meiner Meinung nach würde eine große Verarbeitungsmenge innerhalb gespeicherter Prozeduren Ihren DB-Server zu einem einzigen Punkt der Inflexibilität machen, wenn es um die Skalierung Ihres Vorgangs geht.

Allerdings erledigen Sie die ganze Arbeit in Ihrem Programm und nicht auf dem SQL-Server. könnte Ermöglichen Sie eine stärkere Skalierung, wenn Sie über mehrere Server verfügen, auf denen Ihr Code ausgeführt wird.Dies gilt natürlich nicht für gespeicherte Prozesse, die nur den normalen Abruf oder die Aktualisierung durchführen, sondern für solche, die mehr Verarbeitungsvorgänge wie das Durchlaufen von Datensätzen durchführen.

VORTEILE

  1. Leistung für das, was sie wert sein kann (vermeidet das Parsen von Abfragen durch DB-Treiber/Planerstellung usw.)
  2. Die Datenmanipulation ist nicht in den C/C++/C#-Code eingebettet, was bedeutet, dass ich weniger Low-Level-Code durchsehen muss.SQL ist weniger ausführlich und einfacher zu durchsuchen, wenn es separat aufgeführt wird.
  3. Aufgrund der Trennung können Benutzer 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 wird einwandfrei funktionieren
  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 in meiner gespeicherten Prozedur veränderbare Bedingungen implementieren, die beim Kunden leicht angepasst werden können.
  9. Es wird einfacher, einige automatisierte Tools zu verwenden, um mein Schema und meine Anweisungen zusammen zu konvertieren, als wenn sie in meinen Code eingebettet werden, wo ich sie aufspüren 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 oder auf solche zugreifen, die eine höhere Serialisierungsebene 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, Such- und Ersetzungsänderungen in SQL durchzuführen, wenn sie sich an derselben Stelle befinden, z. B.Transaktionsisolationsanweisungen für alle gespeicherten Prozesse ändern/hinzufügen.
  13. Ich und der DBA-Mitarbeiter finden, dass es einfacher/bequemer ist, eine separate SQL-Datei zu haben, wenn der DBA meine SQL-Sachen überprüfen muss.
  14. Schließlich müssen Sie sich keine Sorgen über SQL-Injection-Angriffe machen, da ein faules Mitglied Ihres Teams bei der Verwendung eingebetteter SQL-Anweisungen keine parametrisierten Abfragen verwendet hat.

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

Weitere Vorteile für gespeicherte Prozeduren:

  • Verhindern Sie Reverse Engineering (natürlich nur, wenn es mit Verschlüsselung erstellt wurde)
  • 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

Ich falle auf Code Seite.Wir bauen eine Datenzugriffsschicht auf, die von allen Apps (sowohl Web als auch Client) verwendet wird, daher ist sie aus dieser Perspektive trocken.Es vereinfacht die Datenbankbereitstellung, da wir lediglich sicherstellen müssen, dass die Tabellenschemata korrekt sind.Es 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 durchbrechen.Eine Anwendung und ihre Daten sind von Natur aus miteinander verbunden.

Gespeicherte Prozeduren.

Wenn sich ein Fehler verflüchtigt oder sich die Logik etwas ändert, müssen Sie das Projekt nicht neu kompilieren.Darüber hinaus ist der Zugriff von verschiedenen Quellen aus möglich, nicht nur von der Stelle, an der Sie die Abfrage in Ihrem Projekt codiert haben.

Ich glaube nicht, dass es schwieriger ist, gespeicherte Prozeduren zu verwalten. Sie sollten sie nicht direkt in der Datenbank, sondern zunächst in separaten Dateien codieren. Anschließend können Sie sie einfach in der Datenbank ausführen, die Sie einrichten müssen.

Vorteile für gespeicherte Prozeduren:

Einfachere Codeüberprüfung.

Weniger gekoppelt, daher einfacher zu testen.

Leichter abzustimmen.

Aus Sicht des Netzwerkverkehrs ist die Leistung im Allgemeinen besser. Wenn Sie einen Cursor oder ähnliches haben, gibt es nicht mehrere Zugriffe auf die 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 – so können Sie auch relativ schnell jeden Code finden, der eine Tabelle aktualisiert.

Wenn andere Dienste beteiligt sind (z. B. Berichtsdienste), fällt es Ihnen möglicherweise leichter, Ihre gesamte Logik in einer gespeicherten Prozedur statt im Code zu speichern und ihn duplizieren zu müssen

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?

Unter bestimmten Umständen kann dynamisch erstelltes SQL im Code eine bessere Leistung haben als eine gespeicherte Prozedur.Wenn Sie eine gespeicherte Prozedur (z. B. sp_customersearch) erstellt haben, die mit Dutzenden von Parametern extrem kompliziert wird, weil sie sehr flexibel sein muss, können Sie wahrscheinlich zur Laufzeit eine viel einfachere SQL-Anweisung im Code generieren.

Man könnte argumentieren, dass dadurch lediglich ein Teil der Verarbeitung von SQL auf den Webserver verlagert wird, aber im Allgemeinen wäre das eine gute Sache.

Der andere großartige Vorteil dieser Technik besteht darin, dass Sie bei der Suche 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.

Ich mag gespeicherte Prozesse. Ich weiß nicht, wie oft ich mithilfe einer gespeicherten Prozedur eine Änderung an einer Anwendung vornehmen konnte, ohne dass es zu Ausfallzeiten der Anwendung kam.

Als großer Fan von Transact SQL hat sich die Optimierung großer Abfragen für mich als sehr nützlich erwiesen.Habe seit etwa 6 Jahren kein Inline-SQL mehr geschrieben!

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

Leistung – nicht wirklich.In SQL 2000 oder höher sind die Optimierungen des Abfrageplans ziemlich gut und werden zwischengespeichert.Ich bin sicher, dass Oracle usw. ähnliche Dinge tun.Ich glaube nicht, dass Sprocs für die Leistung mehr Anlass geben.

Sicherheit?Warum sollten Sprocs sicherer sein?Sofern Sie nicht ohnehin über eine ziemlich ungesicherte Datenbank verfügen, erfolgt der gesamte Zugriff über Ihre Datenbankadministratoren oder über Ihre Anwendung.Parametrisieren Sie immer alle Abfragen – integrieren Sie niemals etwas aus Benutzereingaben, dann ist alles in Ordnung.

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

Linq ist definitiv die Art und Weise, wie ich jetzt bei einem neuen Projekt vorgehen würde.Sieh dir das an ähnlicher Beitrag.

@Keith

Sicherheit?Warum sollten Sprocs sicherer sein?

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

(Natürlich erhalten sie durch die Ausführung von Sprocs möglicherweise alle Daten, die sie benötigen, aber das hängt von den verfügbaren Sprocs ab.Indem man ihnen Zugriff auf die Tabellen gewährt, erhält man Zugriff auf alles.)

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 den Proc an 1 Platz oder drücken Sie den Code auf alle Webserver, installieren Sie alle Desktop -Apps (ClickOnce möglicherweise helfen) in allen Windows -Feldern neu

Ich bevorzuge gespeicherte Prozesse

Es ist auch einfacher, Leistungstests gegen einen Proc durchzuführen. In Abfrageanalysator Set Statistics IO/Zeit auf Set ShowPlan_Text auf und voila

Sie müssen keinen Profiler ausführen, um genau zu sehen, was aufgerufen wird

nur meine 2 Cent

Ich bevorzuge es, sie im Code zu behalten (unter Verwendung eines ORM, nicht inline oder Ad-hoc), damit sie von der Quellcodeverwaltung abgedeckt werden, ohne dass ich mich mit dem Speichern von .sql-Dateien befassen muss.

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

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

Sie können gespeicherte Prozeduren debuggen, aber es wird Ihnen leichter fallen, die Logik im Code zu debuggen und zu verwalten.Normalerweise beenden Sie die Neukompilierung Ihres Codes jedes Mal, wenn Sie das Datenbankmodell ändern.

Auch gespeicherte Prozeduren mit optionalen Suchparametern sind sehr ineffizient, 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 bei der Suche wiederholt wird.

Wenn es um die Sicherheit geht, sind gespeicherte Prozeduren viel sicherer.Einige haben argumentiert, dass der gesamte Zugriff ohnehin über die Anwendung erfolgt.Was viele Menschen vergessen, ist, dass die meisten Sicherheitsverletzungen innerhalb eines Unternehmens entstehen.Überlegen Sie, wie viele Entwickler den „versteckten“ Benutzernamen und das Passwort für Ihre Anwendung kennen?

Außerdem kann, wie MatthieuF betonte, die Leistung durch weniger Roundtrips zwischen der Anwendung (sei es auf einem Desktop- oder Webserver) und dem Datenbankserver deutlich verbessert werden.

Meiner Erfahrung nach verbessert die Abstraktion des Datenmodells durch gespeicherte Prozeduren auch die Wartbarkeit erheblich.Als jemand, der in der Vergangenheit viele Datenbanken pflegen musste, ist es bei einer erforderlichen Modelländerung eine große Erleichterung, einfach ein oder zwei gespeicherte Prozeduren ändern zu können und die Änderung für ALLE externen Anwendungen völlig transparent zu machen.Oftmals ist Ihre Anwendung nicht die einzige, die auf eine Datenbank verweist – es gibt auch andere Anwendungen, Berichtslösungen usw.Daher kann es bei offenem Zugriff auf die Tabellen mühsam sein, alle betroffenen Punkte aufzuspüren.

Außerdem setze ich in der Plus-Spalte ein Häkchen dafür, dass die SQL-Programmierung in die Hände derjenigen gelegt wird, die darauf spezialisiert sind, und für SPs, die es viel einfacher machen, Code zu isolieren und zu testen/optimieren.

Der einzige Nachteil, den ich sehe, ist, dass viele Sprachen die Übergabe von Tabellenparametern nicht zulassen, sodass die Übergabe einer unbekannten Anzahl von Datenwerten ärgerlich sein kann und einige Sprachen immer noch nicht mit dem Abrufen mehrerer Ergebnismengen aus einer einzigen gespeicherten Prozedur umgehen können (obwohl die Letzteres macht SPs in dieser Hinsicht nicht schlechter als Inline-SQL.

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

Es ist auf jeden Fall einfacher zu warten, wenn Sie es in eine gespeicherte Prozedur einfügen.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.Ich arbeite beispielsweise gerade an einer Anwendung, die über eine Endbenutzer-Weboberfläche und eine administrative Desktop-Anwendung verfügt, die beide (offensichtlich) eine Datenbank gemeinsam nutzen, und ich versuche, so viel Logik wie möglich in der Datenbank beizubehalten.Dies ist ein perfektes Beispiel dafür DRY-Prinzip.

Ich bin fest auf der Seite gespeicherter Prozesse, vorausgesetzt, Sie schummeln nicht und verwenden dynamisches SQL im gespeicherten Prozess.Erstens ermöglicht die Verwendung gespeicherter Prozesse dem Datenbankadministrator, Berechtigungen auf der Ebene der gespeicherten Prozesse und nicht auf der Tabellenebene festzulegen.Dies ist nicht nur für die Bekämpfung von SQL-Injection-Angriffen von entscheidender Bedeutung, sondern auch, um zu verhindern, dass Insider direkt auf die Datenbank zugreifen und Änderungen vornehmen.Dies ist eine Möglichkeit, Betrug zu verhindern.Auf keine Datenbank, die persönliche Informationen (SSNs, Kreditkartennummern usw.) enthält oder die in irgendeiner Weise Finanztransaktionen erstellt, sollte jemals zugegriffen werden, außer über gespeicherte Verfahren.Wenn Sie eine andere Methode verwenden, lassen Sie Ihre Datenbank für Einzelpersonen im Unternehmen weit offen, um gefälschte Finanztransaktionen durchzuführen oder Daten zu stehlen, die für Identitätsdiebstahl verwendet werden können.

Gespeicherte Prozesse sind außerdem viel einfacher zu warten und in der Leistung zu optimieren als von der App gesendetes SQL.Sie ermöglichen dem Datenbankadministrator auch, zu sehen, welche Auswirkungen eine Änderung der Datenbankstruktur auf die Art und Weise hat, wie auf die Daten zugegriffen wird.Ich habe noch nie einen guten Datenbankadministrator getroffen, der dynamischen Zugriff auf die Datenbank ermöglicht.

Wir verwenden gespeicherte Prozeduren mit Oracle-Datenbanken, wo 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 mühsam!Mir gefällt die Art und Weise, wie wir es hier machen, viel besser.Das Erstellen und Testen neuer gespeicherter Prozeduren ist viel einfacher als in Ihrem Code.

Da ist ein

Kleinere Protokolle

Ein weiterer kleiner Vorteil für gespeicherte Prozeduren, der nicht erwähnt wurde:Wenn es um SQL-Verkehr geht, wird ein SP-basierter Datenzugriff generiert viel weniger Verkehr.Dies ist wichtig, wenn Sie den Datenverkehr zur Analyse und Profilerstellung überwachen – die Protokolle sind viel kleiner und lesbarer.

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

Wenn die Abfrage sehr umfangreich ist, ist es besser, sie als gespeicherte Prozedur in der Datenbank zu speichern, anstatt sie vom Code aus zu senden.Auf diese Weise müssen nicht große Mengen an Zeichenfolgen vom Anwendungsserver an die Datenbank gesendet werden, sondern nur die "EXEC SPNAME" Der Befehl wird gesendet.

Dies ist übertrieben, wenn sich der Datenbankserver und der Webserver nicht im selben Netzwerk befinden (z. B. Internetkommunikation).Und selbst wenn das nicht der Fall ist, bedeutet zu viel Stress, dass viel Bandbreite verschwendet wird.

Aber Mann, es ist so schrecklich, mit ihnen umzugehen.Ich vermeide sie, so gut ich kann.

Eine gespeicherte SQL-Proc steigert die Leistung der Abfrage nicht

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

  1. Ihre Code-Implementierung und SQL werden unabhängig voneinander.
  2. Code ist einfacher zu lesen.
  3. Einmal schreiben, mehrmals verwenden.
  4. Einmal ändern
  5. Es ist nicht erforderlich, dem Programmierer interne Details zur Datenbank mitzuteilen.usw. usw.

Gespeicherte Prozeduren sind MEHR wartbar, weil:

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

Codewiederholung ist die am schlimmsten Was Sie tun können, wenn Sie versuchen, eine wartbare Anwendung zu erstellen!

Was passiert, wenn Sie einen Logikfehler finden, der an mehreren Stellen korrigiert werden muss?Es ist wahrscheinlicher, dass Sie vergessen, 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ätzlicher Pluspunkt. Sie können weiterhin unsichere/ineffiziente gespeicherte SQL-Prozeduren schreiben.

Einfacher auf eine andere Datenbank zu portieren – keine Prozesse beim Portieren

Es ist nicht sehr schwierig, alle Ihre gespeicherten Prozeduren per Skript für die Erstellung in einer anderen Datenbank zu erstellen.Tatsächlich ist es so Einfacher als Ihre Tabellen zu exportieren, da Sie sich keine Sorgen um Primär-/Fremdschlüssel machen müssen.

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

Parametrisieren Sie immer alle Abfragen – integrieren Sie niemals etwas aus Benutzereingaben, dann ist alles in Ordnung.

Das gilt für Sprocs und dynamisches 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 der Anwendung als auch der Datenbank) durchgeführt, bevor Sie ohnehin wieder live gingen.


@Guy – ja, du hast recht, mit Sprocs kannst du Anwendungsbenutzer so steuern, dass sie nur den Sproc ausführen können, nicht die zugrunde liegende Aktion.

Meine Frage wäre:Wenn alle über Ihre App darauf zugreifen und dabei Verbindungen und Benutzer mit eingeschränkten Rechten zum Aktualisieren/Einfügen usw. verwenden, bietet diese zusätzliche Ebene dann zusätzliche Sicherheit oder zusätzliche Verwaltung?

Meiner Meinung nach ist eher letzteres der Fall.Wenn sie Ihre Anwendung so manipuliert haben, dass sie sie neu schreiben können, stehen ihnen zahlreiche andere Angriffe zur Verfügung.

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

Etwas, das ich bisher noch nicht erwähnt 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 in Kontakt zu treten, die nicht wirklich viel über SQL lernen möchten.Große – und vor allem ältere – Datenbanken sind nicht gerade einfach zu verstehen, daher bevorzugen Programmierer vielleicht einfach eine einfache Schnittstelle, die ihnen alles bietet, was sie brauchen:Lassen Sie die Datenbankadministratoren herausfinden, wie sie die 17 Tabellen zusammenführen, um dies zu erreichen.

Allerdings sind die zum Schreiben gespeicherter Prozeduren verwendeten Sprachen (PL/SQL ist ein berüchtigtes Beispiel) ziemlich brutal.Sie bieten normalerweise nicht die Feinheiten, die man heute in den beliebten Imperativ-, OOP- oder funktionalen Sprachen sieht.Denken Sie an COBOL.

Bleiben Sie also bei gespeicherten Prozeduren, die lediglich die relationalen Details abstrahieren, und nicht bei solchen, die Geschäftslogik enthalten.

Ich schreibe im Allgemeinen OO-Code.Ich vermute, dass es den meisten von Ihnen wahrscheinlich auch so geht.In diesem Zusammenhang scheint mir klar, dass die gesamte Geschäftslogik – einschließlich SQL-Abfragen – in die Klassendefinitionen gehört.Die Logik so aufzuteilen, dass sich ein Teil davon im Objektmodell und ein anderer Teil in der Datenbank befindet, ist nicht besser, als Geschäftslogik in die Benutzeroberfläche zu integrieren.

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

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

2) SQL-Injection/parametrisierte Abfragen.Dieser Einwand ist ein Ablenkungsmanöver.Inline-SQL – sogar dynamisch generiertes Inline-SQL – kann genauso vollständig parametrisiert werden wie jeder gespeicherte Prozess und kann genauso einfach in jeder modernen Sprache durchgeführt werden, die sich lohnt.Hier gibt es in beiden Fällen keinen Vorteil.(„Faule Entwickler machen sich möglicherweise nicht die Mühe, Parameter zu verwenden“ ist kein berechtigter Einwand.Wenn Sie Entwickler in Ihrem Team haben, die es vorziehen, Benutzerdaten einfach in ihrem SQL zu verketten, anstatt Parameter zu verwenden, versuchen Sie zunächst, sie zu schulen, und entlassen sie dann, wenn das nicht funktioniert, genau wie Sie es mit Entwicklern tun würden, die andere haben schlechte, nachweislich schädliche Angewohnheit.)

Ich bin ein großer Befürworter von Code gegenüber SPROCs.Der wichtigste Grund ist die enge Verknüpfung des Codes, gefolgt von der einfachen Quellcodeverwaltung ohne viele benutzerdefinierte Dienstprogramme zum Einbinden.

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

Dadurch bleiben unser Code und unsere SQL-Aufrufe in derselben Versionskontrolle gespeichert, ohne dass wir „vergessen“, einige externe Anwendungen zur Aktualisierung auszuführen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top