Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Dynamisches SQL vs. gespeicherte Prozedur

Dynamisches SQL und gespeicherte Prozeduren sind zwei der wichtigsten Komponenten von SQL Server. In diesem Artikel werden wir uns die Vor- und Nachteile der einzelnen ansehen und wann sie verwendet werden.

Leistung

Jeder kennt die Antwort auf diese Frage. Gespeicherte Prozeduren übertreffen dynamisches SQL in Bezug auf die Leistung. Eine gespeicherte Prozedur wird im Serverspeicher zwischengespeichert und ihre Ausführung ist viel schneller als dynamisches SQL. Wenn alle verbleibenden Variablen konstant gehalten werden, übertrifft die gespeicherte Prozedur dynamisches SQL.

Trennung von Bedenken

In Bezug auf die Trennung von Bedenken schlagen gespeicherte Prozeduren dynamisches SQL um Längen.

Gespeicherte Prozeduren ermöglichen es Ihnen, Ihre Datenbanklogik von Ihrer Geschäftslogik zu trennen. Wenn also ein Fehler in Ihrer Geschäftslogik auftritt, müssen Sie nur Ihren Anwendungscode ändern. Wenn umgekehrt ein Problem mit Ihrer Datenbanklogik auftritt, muss nur Ihre gespeicherte Prozedur geändert werden. Außerdem muss der Anwendungscode nicht neu kompiliert und bereitgestellt werden, wenn eine gespeicherte Prozedur aktualisiert wird.

Wenn Sie in Ihrem Clientcode dynamische SQL-Abfragen verwenden, müssen Sie den Anwendungscode aktualisieren, wenn in der SQL-Abfrage ein Fehler auftritt. Das bedeutet, dass Sie den Anwendungscode neu kompilieren und bereitstellen müssen.

Netzwerkverkehr

Gespeicherte Prozeduren erzeugen weniger Netzwerkverkehr als dynamisches SQL, da zum Ausführen einer gespeicherten Prozedur nur der Prozedurname und die Parameter (falls vorhanden) über das Netzwerk gesendet werden müssen.

Die Ausführung von dynamischem SQL erfordert, dass die vollständige Abfrage über das Netzwerk gesendet wird, was den Netzwerkverkehr erhöht, insbesondere wenn die Abfrage sehr umfangreich ist.

SQL-Injection-Angriffe

Gespeicherte Prozeduren sind nicht anfällig für SQL-Injection-Angriffe.

Dynamische SQL-Abfragen sind anfällig für SQL-Injection-Angriffe, wenn keine parametrisierten Abfragen verwendet werden, und parametrisierte Abfragen können nicht mit dynamischem SQL verwendet werden, wenn ein Tabellen- oder Spaltenname als Parameter übergeben wird.

In diesem Fall besteht die Problemumgehung darin, dass die Codename-Funktion verwendet werden kann, um SQL-Injection-Angriffe zu verhindern.

Wiederverwendbarkeit von zwischengespeicherten Abfrageplänen

Gespeicherte Prozeduren verbessern die Datenbankleistung, da sie die Wiederverwendung zwischengespeicherter Abfragepläne ermöglichen. Im Fall von dynamischem SQL müssen Sie parametrisierte Abfragen verwenden, um die Wiederverwendbarkeit von zwischengespeicherten Abfrageplänen zu erhöhen. In Ermangelung parametrisierter Abfragepläne erkennt SQL Server automatisch Parameter und generiert zwischengespeicherte Abfragepläne, was zu einer verbesserten Leistung führt.

Es ist wichtig, hier zu erwähnen, dass nur OLTP-Systeme von der Wiederverwendbarkeit zwischengespeicherter Abfragepläne profitieren. Im Fall von OLAP-Systemen ändert sich die Wahl des Optimierers, OLAP-System profitiert von dem einzigartigen Plan.

Wartung

Gespeicherte Prozeduren mit statischem SQL sind einfacher zu warten. Beispielsweise können im Fall von statischem SQL in einer gespeicherten Prozedur Syntaxfehler abgefangen werden, bevor sie ausgeführt werden. Im Fall von dynamischem SQL in gespeicherten Prozeduren können Syntaxfehler nicht vor der Abfrageausführung abgefangen werden.

Außerdem ähneln Stored Procedures eher Funktionen, sie werden einmal definiert und können dann überall im Skript aufgerufen werden. Wenn Sie also eine gespeicherte Prozedur aktualisieren möchten, müssen Sie sie nur an einer Stelle aktualisieren. Alle Anwendungsteile, die die gespeicherte Prozedur aufrufen, haben Zugriff auf die aktualisierte Version. Ein Nachteil ist jedoch, dass auch die Anwendungsteile betroffen sein können, bei denen Sie die aktualisierte gespeicherte Prozedur nicht möchten. Im Fall von dynamischem SQL müssen Sie möglicherweise SQL-Skripte an mehreren Stellen schreiben, aber in solchen Fällen wirkt sich das Aktualisieren des Skripts an einer Stelle nicht auf die andere aus. Eine Entscheidung zwischen der Verwendung einer gespeicherten Prozedur und dynamischem SQL hängt von der Anwendungsfunktionalität ab.

Sicherheit

Wenn mehrere Anwendungen auf die Datenbank zugreifen, ist es sicherer, gespeicherte Prozeduren als dynamisches SQL zu verwenden.

Gespeicherte Prozeduren bieten eine zusätzliche Sicherheitsebene, während der Benutzerkontext die einzige Möglichkeit ist, Berechtigungen für dynamische SQL-Skripts zu steuern. Alles in allem ist das Sichern von dynamischem SQL im Vergleich zu gespeicherten Prozeduren mühsam.

Identifizieren von Abhängigkeiten

In einer relationalen Datenbank haben Tabellen Abhängigkeiten von anderen Tabellen in der Datenbank.

Stellen Sie sich ein Szenario vor, in dem Sie eine Tabelle entfernen möchten, aber vorher alle Tabellenabhängigkeiten herausfinden möchten. Oder einfach ausgedrückt, Sie möchten die Abfragen finden, die auf die Tabelle zugreifen, die Sie löschen möchten. In diesen Fällen können Sie die gespeicherte Prozedur sp_depends verwenden.

sp_depends kann jedoch nur die Abhängigkeiten erkennen, bei denen statisches SQL innerhalb einer gespeicherten Prozedur verwendet wird. Wenn dynamisches SQL von einer Tabelle abhängig ist, kann diese Abhängigkeit von der gespeicherten Prozedur sp_depends nicht erkannt werden. Lassen Sie uns dies anhand eines einfachen Beispiels in Aktion sehen.

Dummy-Daten vorbereiten

Lassen Sie uns einige Dummy-Daten erstellen, um das Konzept der Abhängigkeiten in statischem und dynamischem SQL zu erklären.

CREATE DATABASE deptest;

USE deptest
CREATE TABLE student
(

	Id int identity primary key,
	Name VARCHAR(50) NOT NULL,
	Gender VARCHAR(50) NOT NULL,
	Age int
)

INSERT INTO student

VALUES
('James', 'Male', 20),
('Helene', 'Female', 20),
('Sofia', 'Female', 20),
('Ed', 'Male', 20),
('Ron', 'Female', 20)

Jetzt haben wir eine Testdatenbank, die eine Tabelle und einige Testdaten enthält. Lassen Sie uns nun zwei gespeicherte Prozeduren erstellen, die auf die Schülertabelle zugreifen.

Die erste gespeicherte Prozedur verwendet statisches SQL, um alle Datensätze aus der Schülertabelle abzurufen:

USE deptest
GO
CREATE PROC spStatProc
AS
BEGIN
	SELECT * FROM student
END

Führen Sie das obige Skript aus. Dieses Skript erstellt eine gespeicherte Prozedur „spStatProc“ in der Datenbank deptest.

Lassen Sie uns eine weitere gespeicherte Prozedur erstellen, die dynamisches SQL enthält, das alle Datensätze aus der Schülertabelle abruft.

USE deptest
GO
CREATE PROC spDynProc
AS
BEGIN
	DECLARE @query NVARCHAR(100)
	SET @query = 'SELECT * FROM student'
	EXECUTE sp_execute @query
	
END

Dieses Skript erstellt eine gespeicherte Prozedur „spDynProc“ in der deptest-Datenbank. Diese gespeicherte Prozedur verwendet eine dynamische SQL-Anweisung, um alle Datensätze aus der Schülertabelle abzurufen.

Jetzt haben wir zwei gespeicherte Prozeduren, die eine Abhängigkeit von der Schülertabelle haben. Einer von ihnen enthält statisches SQL und der andere enthält dynamisches SQL.

Wenn Sie jedoch die gespeicherte Prozedur sp_depends ausführen und ihr die Studententabelle als Parameter übergeben, werden Sie sehen, dass sie nur die gespeicherte Prozedur „spStatProc“ abruft. Dies liegt daran, dass es statisches SQL enthält. Die gespeicherte Prozedur „spDynProc“ wird ignoriert, da sie dynamisches SQL enthält.

Führen Sie das folgende Skript aus.

USE deptest
GO
EXECUTE sp_depends student

Es wird die folgende Ausgabe erhalten:

[Tabellen-ID=40 /]

Sie können sehen, dass sp_depends die „spDynProc“-Abhängigkeit nicht melden konnte und nur „spStatProc“ meldete.

Komplexität

Gespeicherte Prozeduren können extrem komplex werden, wenn Sie eine große Anzahl von Filtern verwenden und mehrere AND- und OR-Klauseln zwischen den Filtern vorhanden sind. Andererseits können Sie mit dynamischem SQL abhängig vom Filtertyp WHERE-Klauseln dynamisch generieren. Dies macht dynamisches SQL zur besseren Wahl, wenn Sie extrem komplexe Logik implementieren möchten.

Schlussfolgerung

Insgesamt übertrifft die gespeicherte Prozedur dynamisches SQL in fast allen Aspekten. Sie sind schneller, sicherer und einfacher zu warten und erfordern weniger Netzwerkverkehr. Als Faustregel gilt, dass gespeicherte Prozeduren in Szenarien verwendet werden sollten, in denen Sie Ihre Abfragen nicht ändern müssen und Ihre Abfragen nicht sehr komplex sind. Wenn Sie jedoch häufig Tabellennamen, Spaltennamen oder die Anzahl der Parameter in Ihrer Abfrage ändern, ist Dynamic SQL aufgrund seiner einfacheren Implementierungsstrategie die bessere Wahl.

Nützliche Links

  • Dynamisches SQL im Vergleich zu gespeicherten Prozeduren
  • Keine Angst vor Dynamic SQL
  • Erstellen leistungsstarker gespeicherter Prozeduren
  • Klassen zu gespeicherten Prozeduren