Angenommen, ich muss einen Teil des T-SQL-Codes implementieren, der als Ergebnis eine Tabelle zurückgeben muss. Ich kann eine Tabellenwertfunktion oder eine gespeicherte Prozedur implementieren, die eine Reihe von Zeilen zurückgibt. Was soll ich verwenden?
Kurz gesagt, was ich wissen möchte, ist:
Was sind die Hauptunterschiede zwischen Funktionen und gespeicherten Prozeduren? Welche Überlegungen muss ich bei der Verwendung des einen oder anderen berücksichtigen?
Antworten:
Wenn Sie das Ergebnis dieses Codeteils wahrscheinlich mit anderen Tabellen kombinieren möchten, können Sie die Ergebnisse natürlich mit einer Tabellenwertfunktion in einer einzigen SELECT-Anweisung zusammenstellen.
Im Allgemeinen gibt es eine Hierarchie (View <TV Function <Stored Proc). Sie können in jedem einzelnen mehr tun, aber die Fähigkeit, die Ausgaben zusammenzustellen und das Optimierungsprogramm wirklich einzubeziehen, nimmt mit zunehmender Funktionalität ab.
Verwenden Sie also dasjenige, mit dem Sie Ihr gewünschtes Ergebnis minimal ausdrücken können.
quelle
Funktionen müssen deterministisch sein und können nicht zum Vornehmen von Änderungen an der Datenbank verwendet werden, wohingegen gespeicherte Prozeduren das Einfügen und Aktualisieren usw. ermöglichen.
Sie sollten die Verwendung von Funktionen einschränken, da diese ein großes Skalierbarkeitsproblem für große, komplexe Abfragen darstellen. Sie werden zu einer Art "Black Box" für den Abfrageoptimierer, und Sie werden enorme Leistungsunterschiede zwischen der Verwendung von Funktionen und dem einfachen Einfügen des Codes in eine Abfrage feststellen.
Aber sie sind definitiv nützlich für Tabellenrenditen in ganz bestimmten Fällen.
Wenn Sie eine durch Kommas getrennte Liste analysieren müssen, um die Übergabe eines Arrays an eine Prozedur zu simulieren, kann eine Funktion die Liste in eine Tabelle für Sie verwandeln. Dies ist bei SQL Server 2005 üblich, da wir noch keine Tabellen an gespeicherte Prozeduren übergeben können (dies ist bei 2008 möglich).
quelle
Aus den Dokumenten :
quelle
Ich werde einige interessante Unterschiede zwischen gespeicherten Prozeduren und Funktionen schreiben.
Wir können keine nicht deterministischen Funktionen in Funktionen verwenden, aber wir können nicht deterministische Funktionen in gespeicherten Prozeduren verwenden. Nun stellt sich die Frage, was nicht deterministische Funktion ist. Ans ist: -
Ausnahme:-
Wir können DML-Anweisungen (Einfügen, Aktualisieren, Löschen) innerhalb einer gespeicherten Prozedur verwenden, aber wir können DML-Anweisungen nicht in Funktionen für physische Tabellen oder permanente Tabellen verwenden. Wenn wir DML-Operationen in Funktionen ausführen möchten, können wir dies über Tabellenvariablen tun, die nicht für permanente Tabellen gelten.
Wir können die Fehlerbehandlung nicht innerhalb der Funktion verwenden, aber wir können die Fehlerbehandlung in gespeicherten Prozeduren durchführen.
quelle
Die Prozedur kann null oder n Werte zurückgeben, während die Funktion einen obligatorischen Wert zurückgeben kann.
Prozeduren können Eingabe- / Ausgabeparameter haben, während Funktionen nur Eingabeparameter haben können.
Die Prozedur erlaubt sowohl die Select- als auch die DML-Anweisung, während die Funktion nur die Select-Anweisung darin zulässt.
Funktionen können von der Prozedur aufgerufen werden, während Prozeduren nicht von der Funktion aufgerufen werden können.
Die Ausnahme kann vom Try-Catch-Block in einer Prozedur behandelt werden, während der Try-Catch-Block in einer Funktion nicht verwendet werden kann.
Wir können das Transaktionsmanagement im Verfahren durchführen, während wir die Funktion nicht übernehmen können.
Prozeduren können nicht in einer select-Anweisung verwendet werden, während die Funktion in eine select-Anweisung eingebettet werden kann.
UDF (User Defined Function) kann in den SQL-Anweisungen an einer beliebigen Stelle im Abschnitt
WHERE
/HAVING
/ verwendet werden,SELECT
während gespeicherte Prozeduren dies nicht können.UDFs, die Tabellen zurückgeben, können als ein anderes Rowset behandelt werden. Dies kann in
JOIN
s mit anderen Tabellen verwendet werden.Inline-UDFs können jedoch als Ansichten verwendet werden, die Parameter annehmen und in
JOIN
s- und anderen Rowset-Operationen verwendet werden können.quelle
Wenn Sie eine Funktion haben, können Sie diese beispielsweise als Teil Ihrer SQL-Anweisung verwenden
Bei den gespeicherten Prozeduren funktioniert dies nicht.
quelle
Ich habe einige Tests mit einer langen Logik ausgeführt, wobei das gleiche Codebit (eine lange SELECT-Anweisung) sowohl in einer Tabellenwertfunktion als auch in einer gespeicherten Prozedur und einer geraden EXEC / SELECT-Funktion ausgeführt wurde und jeweils identisch ausgeführt wurde.
Meiner Meinung nach verwenden Sie immer eine Tabellenwertfunktion anstelle einer gespeicherten Prozedur, um eine Ergebnismenge zurückzugeben, da dies die Logik in Abfragen, die anschließend mit ihnen verknüpft werden, viel einfacher und lesbarer macht und es Ihnen ermöglicht, dieselbe Logik wiederzuverwenden. Um zu viele Leistungseinbußen zu vermeiden, verwende ich häufig "optionale" Parameter (dh Sie können NULL an sie übergeben), damit die Funktion die Ergebnismenge schneller zurückgeben kann, z.
Auf diese Weise können Sie diese Funktion für viele verschiedene Situationen verwenden und keinen großen Leistungseinbruch erleiden. Ich glaube, das ist effizienter als das anschließende Filtern:
Ich habe diese Technik in mehreren Funktionen verwendet, manchmal mit einer langen Liste von "optionalen" Parametern dieses Typs.
quelle
Ich persönlich verwende Tabellenwertfunktionen, wenn ich nur eine einzelne Tabelle ohne Auswirkungen zurückgebe. Grundsätzlich behandle ich sie wie parametrisierte Ansichten.
Wenn mehrere Datensätze zurückgegeben werden müssen oder wenn Werte in Tabellen aktualisiert werden, verwende ich eine gespeicherte Prozedur.
Meine 2 Cent
quelle
Wie oben erwähnt, sind Funktionen besser lesbar / zusammensetzbar / selbstdokumentierend, aber im Allgemeinen weniger performant und können ernsthaft weniger performant sein, wenn Sie sie in Verknüpfungen wie z
Oft muss man nur die Redundanz des Codes akzeptieren, die ein Fernsehgerät beseitigen könnte (zu inakzeptablen Leistungskosten).
Ein weiterer Punkt, den ich noch nicht erwähnt habe, ist, dass Sie keine temporären Tabellen zur Änderung des Datenbankstatus in einem TVF mit mehreren Anweisungen verwenden können. Der funktional am besten zu einer temporären Tabelle äquivalente Mechanismus ist die Änderung der Speichertabellenvariablen ohne Status. Bei großen Datenmengen ist eine temporäre Tabelle wahrscheinlich leistungsfähiger als eine Tabellenvariable. (Andere Alternativen sind dynamische Tabellen und allgemeine Ausdrücke mit Tabellenwerten, aber bei einer gewissen Komplexität sind diese keine gute Option mehr, IMO.)
quelle
Ich würde beides perfromance testen. Es ist wahrscheinlich, dass der sp-Ansatz oder eine abgeleitete Tabelle erheblich schneller als eine Funktion ist, und wenn ja, sollte dieser Ansatz verwendet werden. Im Allgemeinen vermeide ich Funktionen, da sie Leistungsfresser sein können.
quelle
Es hängt davon ab :) Wenn Sie das Ergebnis mit Tabellenwert in einer anderen Prozedur verwenden möchten, sollten Sie eine TableValued-Funktion verwenden. Wenn die Ergebnisse für einen Kunden sind, ist der gespeicherte Prozess normalerweise der bessere Weg.
quelle
Gespeicherte Prozeduren sind vorkompilierte Abfragen, die schneller ausgeführt und vor den SQL-Injektionen geschützt werden. Sie können 0 oder N Werte zurückgeben. Wir können DML-Operationen innerhalb der gespeicherten Prozeduren ausführen. Wir können Funktionen innerhalb der Prozeduren und Funktionen in der Auswahlabfrage verwenden. Funktionen werden verwendet, um Werte zurückzugeben, und DML-Operationen sind in Funktionen nicht möglich. Es gibt zwei Arten von Funktionen, die skalar und tabellarisch sind. Die Skalarfunktion gibt eine Einzelwertfunktion mit Tabellenwerten zurück, mit der Tabellenzeilen zurückgegeben werden.
quelle