PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Warum können PL/pgSQL-Funktionen Nebenwirkungen haben, während SQL-Funktionen dies nicht können?

Sie haben den Schlüsselsatz im Handbuch selbst fett gedruckt:

Der gesamte Körper einer SQL-Funktion wird geparst, bevor sie ausgeführt wird.

Lesen Sie auch über Die Parser-Phase im Handbuch.

Es besteht aus zwei Hauptteilen:dem Parser und der Wandlungsprozess . Zitat aus dem Handbuch:

der Wandlungsprozess nimmt den vom Parser zurückgegebenen Baum als Eingabe und führt die semantische Interpretation durch, die erforderlich ist, um zu verstehen, welche Tabellen, Funktionen und Operatoren von der Abfrage referenziert werden.

Wenn eine SQL-Funktion diese Befehle enthält:

CREATE TABLE foo (...);
INSERT INTO foo VALUES(...);

Beide Anweisungen werden praktisch gleichzeitig geplant (basierend auf derselben Momentaufnahme der Systemkataloge). Daher das INSERT kann die vermutlich mit dem vorherigen CREATE erstellte Tabelle "foo" nicht sehen Befehl. Dadurch entsteht eines der folgenden Probleme :

  1. Wenn es keinen anderen gibt Tabelle namens "foo" in Ihrem search_patch (noch) beschwert sich Postgres beim Erstellen die Funktion:

    ERROR:  relation "foo" does not exist
    
  2. Wenn in Ihrem search_patch bereits eine andere Tabelle mit dem Namen "foo" existiert (und Sie verwenden keine widersprüchlichen Spaltennamen), Postgres plant das INSERT basierend auf dieser bereits vorhandenen Tabelle. Normalerweise führt dies zur Ausführungszeit zu einem Fehler , wenn irgendwelche Werte Konflikte in der (falschen!) Tabelle verursachen. Oder, mit etwas Pech, könnte es sogar ohne Fehlermeldung in diese Tabelle schreiben! Sehr hinterhältiger Fehler.

Das kann bei einem PL/pgSQL nicht passieren Funktion, weil sie SQL-Befehle wie vorbereitete Anweisungen behandelt, die sequenziell geplant und ausgeführt werden . So kann jede Anweisung Objekte sehen, die in vorherigen Anweisungen erstellt wurden.

Anweisungen, die nie besucht werden, sind daher - anders als bei SQL-Funktionen - nie geplant. Und der Ausführungsplan für Anweisungen kann innerhalb derselben Sitzung zwischengespeichert werden - ebenfalls im Gegensatz zu SQL-Funktionen. Lesen Sie Details zum Plan-Caching in PL/pgSQL-Funktionen im Handbuch hier.
Jeder Ansatz hat Vorteile für einige Anwendungsfälle. Weiterführende Literatur:

  • Unterschied zwischen Sprache sql und Sprache plpgsql in PostgreSQL-Funktionen