MySQL gespeicherte Prozedur vs Funktion, welche würde ich wann verwenden?

160

Ich betrachte gespeicherte MySQL-Prozeduren und -Funktionen. Was ist der wahre Unterschied?

Sie scheinen ähnlich zu sein, aber eine Funktion hat mehr Einschränkungen.

Ich liege wahrscheinlich falsch, aber es scheint, dass eine gespeicherte Prozedur alles kann und mehr eine gespeicherte Funktion. Warum / wann würde ich eine Prozedur gegen eine Funktion verwenden?

Anonym
quelle

Antworten:

101

Sie können gespeicherte Prozeduren nicht mit normalem SQL mischen, während Sie dies mit gespeicherten Funktionen können.

zB SELECT get_foo(myColumn) FROM mytableist nicht gültig, wenn get_foo()es sich um eine Prozedur handelt, aber Sie können dies tun, wenn get_foo()es sich um eine Funktion handelt. Der Preis ist, dass Funktionen mehr Einschränkungen haben als eine Prozedur.

nr
quelle
18
Welche Einschränkungen haben Funktionen?
Fantius
11
Ah, ich habe hier einige gute Informationen gefunden: dev.mysql.com/doc/refman/5.0/en/…
Fantius
262

Der allgemeinste Unterschied zwischen Prozeduren und Funktionen besteht darin, dass sie unterschiedlich und für unterschiedliche Zwecke aufgerufen werden:

  1. Eine Prozedur gibt keinen Wert zurück. Stattdessen wird es mit einer CALL-Anweisung aufgerufen, um eine Operation auszuführen, z. B. das Ändern einer Tabelle oder das Verarbeiten abgerufener Datensätze.
  2. Eine Funktion wird innerhalb eines Ausdrucks aufgerufen und gibt einen einzelnen Wert direkt an den Aufrufer zurück, der im Ausdruck verwendet werden soll.
  3. Sie können weder eine Funktion mit einer CALL-Anweisung noch eine Prozedur in einem Ausdruck aufrufen.

Die Syntax für die Routineerstellung unterscheidet sich für Prozeduren und Funktionen etwas:

  1. Prozedurparameter können als Nur-Eingabe, Nur-Ausgabe oder beides definiert werden. Dies bedeutet, dass eine Prozedur mithilfe von Ausgabeparametern Werte an den Aufrufer zurückgeben kann. Auf diese Werte kann in Anweisungen zugegriffen werden, die auf die CALL-Anweisung folgen. Funktionen haben nur Eingabeparameter. Obwohl sowohl Prozeduren als auch Funktionen Parameter haben können, unterscheidet sich die Deklaration der Prozedurparameter von der für Funktionen.
  2. Funktionen geben den Wert zurück, daher muss eine Funktionsdefinition eine RETURNS-Klausel enthalten, um den Datentyp des Rückgabewerts anzugeben. Außerdem muss mindestens eine RETURN-Anweisung im Funktionskörper vorhanden sein, um einen Wert an den Aufrufer zurückzugeben. RETURNS und RETURN erscheinen nicht in Prozedurdefinitionen.

    • Verwenden Sie die, um eine gespeicherte Prozedur aufzurufen CALL statement. Um eine gespeicherte Funktion aufzurufen, verweisen Sie in einem Ausdruck darauf. Die Funktion gibt während der Ausdrucksauswertung einen Wert zurück.

    • Eine Prozedur wird mit einer CALL-Anweisung aufgerufen und kann Werte nur mit Ausgabevariablen zurückgeben. Eine Funktion kann wie jede andere Funktion aus einer Anweisung heraus aufgerufen werden (dh durch Aufrufen des Funktionsnamens) und einen skalaren Wert zurückgeben.

    • Die Angabe eines Parameters als IN, OUT oder INOUT gilt nur für ein PROCEDURE. Für eine FUNKTION werden Parameter immer als IN-Parameter betrachtet.

    Wenn vor einem Parameternamen kein Schlüsselwort angegeben wird, handelt es sich standardmäßig um einen IN-Parameter. Vor Parametern für gespeicherte Funktionen steht nicht IN, OUT oder INOUT. Alle Funktionsparameter werden als IN-Parameter behandelt.

Verwenden Sie zum Definieren einer gespeicherten Prozedur oder Funktion CREATE PROCEDURE bzw. CREATE FUNCTION:

CREATE PROCEDURE proc_name ([parameters])
 [characteristics]
 routine_body


CREATE FUNCTION func_name ([parameters])
 RETURNS data_type       // diffrent
 [characteristics]
 routine_body

Eine MySQL-Erweiterung für gespeicherte Prozeduren (keine Funktionen) besteht darin, dass eine Prozedur eine Ergebnismenge oder sogar mehrere Ergebnismengen generieren kann, die der Aufrufer auf dieselbe Weise wie das Ergebnis einer SELECT-Anweisung verarbeitet. Der Inhalt solcher Ergebnismengen kann jedoch nicht direkt im Ausdruck verwendet werden.

Gespeicherte Routinen (die sich sowohl auf gespeicherte Prozeduren als auch auf gespeicherte Funktionen beziehen ) sind genau wie Tabellen oder Ansichten einer bestimmten Datenbank zugeordnet. Wenn Sie eine Datenbank löschen, werden auch alle in der Datenbank gespeicherten Routinen gelöscht.

Gespeicherte Prozeduren und Funktionen haben nicht denselben Namespace. Es ist möglich, eine Prozedur und eine Funktion mit demselben Namen in einer Datenbank zu haben.

In gespeicherten Prozeduren kann dynamisches SQL verwendet werden, jedoch nicht in Funktionen oder Triggern.

SQL-vorbereitete Anweisungen (PREPARE, EXECUTE, DEALLOCATE PREPARE) können in gespeicherten Prozeduren verwendet werden, jedoch nicht in gespeicherten Funktionen oder Triggern. Daher können gespeicherte Funktionen und Trigger Dynamic SQL nicht verwenden (wobei Sie Anweisungen als Zeichenfolgen erstellen und diese dann ausführen). (Dynamisches SQL in gespeicherten MySQL-Routinen)

Einige weitere interessante Unterschiede zwischen FUNCTION und STORED PROCEDURE:

  1. ( Dieser Punkt wird aus einem Blogpost kopiert . ) Die gespeicherte Prozedur ist ein vorkompilierter Ausführungsplan, bei dem es sich nicht um Funktionen handelt. Funktion Zur Laufzeit analysiert und kompiliert. Gespeicherte Prozeduren, als Pseudocode in der Datenbank gespeichert, dh in kompilierter Form.

  2. ( Ich bin mir in diesem Punkt nicht sicher. )
    Gespeicherte Prozeduren haben die Sicherheit und reduzieren den Netzwerkverkehr. Außerdem können wir gespeicherte Prozeduren in jeder beliebigen Nummer aufrufen. von Anwendungen zu einem Zeitpunkt. Referenz

  3. Funktionen werden normalerweise für Berechnungen verwendet, wobei normalerweise Prozeduren zum Ausführen von Geschäftslogik verwendet werden.

  4. Funktionen Kann den Status der Datenbank nicht beeinflussen (Anweisungen, die explizites oder implizites Festschreiben oder Zurücksetzen ausführen, sind in der Funktion nicht
    zulässig ). Gespeicherte Prozeduren können den Status der Datenbank mithilfe von Festschreiben usw. beeinflussen. Aktualisierung: J.1. Einschränkungen für gespeicherte Routinen und Trigger

  5. Funktionen können keine FLUSH- Anweisungen verwenden, während gespeicherte Prozeduren dies können.

  6. Gespeicherte Funktionen können nicht rekursiv sein, während gespeicherte Prozeduren rekursiv sein können. Hinweis: Rekursive gespeicherte Prozeduren sind standardmäßig deaktiviert, können jedoch auf dem Server aktiviert werden, indem die Serversystemvariable max_sp_recursion_depth auf einen Wert ungleich Null gesetzt wird. Weitere Informationen finden Sie in Abschnitt 5.2.3, „Systemvariablen“ .

  7. Innerhalb einer gespeicherten Funktion oder eines gespeicherten Triggers ist es nicht zulässig, eine Tabelle zu ändern, die bereits von der Anweisung, die die Funktion oder den Trigger aufgerufen hat, zum Lesen oder Schreiben verwendet wird. Gutes Beispiel: Wie aktualisiere ich dieselbe Tabelle beim Löschen in MYSQL?

Hinweis : Obwohl einige Einschränkungen normalerweise für gespeicherte Funktionen und Trigger gelten, jedoch nicht für gespeicherte Prozeduren, gelten diese Einschränkungen für gespeicherte Prozeduren, wenn sie aus einer gespeicherten Funktion oder einem gespeicherten Trigger heraus aufgerufen werden. Obwohl Sie FLUSH beispielsweise in einer gespeicherten Prozedur verwenden können, kann eine solche gespeicherte Prozedur nicht von einer gespeicherten Funktion oder einem gespeicherten Trigger aufgerufen werden.

Grijesh Chauhan
quelle
2
@GrijeshChauhan, Was meinst du mit "Funktion analysiert und zur Laufzeit kompiliert" ?
Pacerier
@Pacerier bedeutet, dass Funktionen in MySQL so etwas wie Skripte sind, die kompiliert und im laufenden Betrieb ausgeführt werden. Ich habe es aus einem Blog-Beitrag kopiert , aber keine praktischen Übungen durchgeführt, um dieses Verhalten zu überprüfen.
Grijesh Chauhan
In Prozeduren können Sie eine out-Variable als Parameter übergeben und sie dann mit einer select-Anweisung
aufrufen
1
Punkt 4 im unteren Teil dieser Antwort ist meiner Meinung nach der Kern des Unterschieds zwischen Prozeduren und Funktionen. Prozeduren können die Datenbank ändern, Funktionen nicht. Alle anderen Unterschiede dienen nur dazu, diesen Zweck effektiver zu erfüllen.
Woodrow Barlow
51

Ein wesentlicher Unterschied besteht darin, dass Sie eine Funktion in Ihre SQL-Abfragen aufnehmen können, gespeicherte Prozeduren jedoch nur mit der folgenden CALLAnweisung aufgerufen werden können :

UDF-Beispiel:

CREATE FUNCTION hello (s CHAR(20))
   RETURNS CHAR(50) DETERMINISTIC
   RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)

CREATE TABLE names (id int, name varchar(20));
INSERT INTO names VALUES (1, 'Bob');
INSERT INTO names VALUES (2, 'John');
INSERT INTO names VALUES (3, 'Paul');

SELECT hello(name) FROM names;
+--------------+
| hello(name)  |
+--------------+
| Hello, Bob!  |
| Hello, John! |
| Hello, Paul! |
+--------------+
3 rows in set (0.00 sec)

Sproc Beispiel:

delimiter //

CREATE PROCEDURE simpleproc (IN s CHAR(100))
BEGIN
   SELECT CONCAT('Hello, ', s, '!');
END//
Query OK, 0 rows affected (0.00 sec)

delimiter ;

CALL simpleproc('World');
+---------------------------+
| CONCAT('Hello, ', s, '!') |
+---------------------------+
| Hello, World!             |
+---------------------------+
1 row in set (0.00 sec)
Daniel Vassallo
quelle
1
Ihre Funktion hat zwei Rückgaben ? Ich meine, was ist das für eine Zeile? RETURNS CHAR(50) DETERMINISTIC?
Martin AJ
Die RETURNS CHAR(50)Zustände , welche von Datentyp zurückgegeben. Dies RETURN CONCAT(...sind die Daten, die zurückgegeben werden. Beides wird benötigt. Das DETERMINISTICwird benötigt, um anzugeben, dass die zugrunde liegenden Daten nicht geändert werden.
Lemming622
8

Eine gespeicherte Funktion kann innerhalb einer Abfrage verwendet werden. Sie können es dann auf jede Zeile oder innerhalb einer WHERE-Klausel anwenden.

Eine Prozedur wird mit der CALL-Abfrage ausgeführt.

Evert
quelle
0

Gespeicherte Prozeduren können rekursiv aufgerufen werden, gespeicherte Funktionen jedoch nicht

palash140
quelle