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

Unterschied zwischen Sprache sql und Sprache plpgsql in PostgreSQL-Funktionen

SQL-Funktionen

... sind die bessere Wahl:

  • Für einfache skalare Abfragen . Nicht viel zu planen, sparen Sie sich besser den Overhead.

  • Für einzelne (oder sehr wenige) Anrufe pro Sitzung . Vom Plan-Caching über vorbereitete Anweisungen, die PL/pgSQL zu bieten hat, ist nichts zu gewinnen. Siehe unten.

  • Wenn sie normalerweise im Zusammenhang mit größeren Abfragen aufgerufen werden und einfach genug sind, um inline zu werden .

  • Aus Mangel an Erfahrung mit jeder prozeduralen Sprache wie PL/pgSQL. Viele kennen sich gut mit SQL aus und das ist alles, was Sie für SQL-Funktionen brauchen. Nur wenige können dasselbe über PL/pgSQL sagen. (Obwohl es ziemlich einfach ist.)

  • Etwas kürzerer Code. Kein Block-Overhead.

PL/pgSQL-Funktionen

... sind die bessere Wahl:

  • Wenn Sie prozedurale Elemente benötigen oder Variablen die in SQL-Funktionen offensichtlich nicht verfügbar sind.

  • Für jede Art von dynamischem SQL , wo Sie bauen und EXECUTE Aussagen dynamisch. Besondere Sorgfalt ist erforderlich, um eine SQL-Injektion zu vermeiden. Weitere Einzelheiten:

    • Postgres-Funktionen im Vergleich zu vorbereiteten Abfragen
  • Wenn Sie Berechnungen haben die wiederverwendet werden können an mehreren Stellen und ein CTE kann für diesen Zweck nicht gedehnt werden. In einer SQL-Funktion haben Sie keine Variablen und wären gezwungen, wiederholt zu berechnen oder in eine Tabelle zu schreiben. Diese verwandte Antwort auf dba.SE enthält nebeneinander liegende Codebeispiele zur Lösung des gleichen Problems mit einer SQL-Funktion / einer plpgsql-Funktion / einer Abfrage mit CTEs:

    • Wie man einen Parameter an eine Funktion übergibt

Zuordnungen sind etwas teurer als in anderen Verfahrenssprachen. Passen Sie einen Programmierstil an, der nicht mehr Zuweisungen als nötig verwendet.

  • Wenn eine Funktion nicht eingebettet werden kann und wiederholt aufgerufen wird. Anders als bei SQL-Funktionen können Abfragepläne zwischengespeichert werden für alle SQL-Anweisungen innerhalb einer PL/pgSQL-Funktion; sie werden wie vorbereitete Aussagen behandelt , wird der Plan für wiederholte Aufrufe innerhalb derselben Sitzung zwischengespeichert (wenn Postgres erwartet, dass der zwischengespeicherte (generische) Plan jedes Mal eine bessere Leistung erbringt als die Neuplanung. Das ist der Grund, warum PL/pgSQL-Funktionen normalerweise schneller in solchen Fällen nach den ersten Anrufen.

    Hier ist ein Thread zu pgsql-performance, in dem einige dieser Punkte diskutiert werden:

    • Re:pl/pgsql-Funktionen übertreffen SQL-Funktionen?
  • Wenn Sie Fehler abfangen müssen .

  • Für Triggerfunktionen .

  • Beim Einschließen von DDL-Anweisungen werden Objekte oder Systemkataloge in irgendeiner Weise geändert, die für nachfolgende Befehle relevant sind, da alle Anweisungen in SQL-Funktionen auf einmal analysiert werden, während PL/pgSQL-Funktionen jede Anweisung nacheinander planen und ausführen (wie eine vorbereitete Anweisung). Siehe:

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

Beachten Sie auch:

  • Leistung gespeicherter PostgreSQL-Prozeduren

Um tatsächlich zurückzukehren von einer PL/pgSQL-Funktion könnten Sie schreiben:

CREATE FUNCTION f2(istr varchar)
  RETURNS text AS
$func$
BEGIN
   RETURN 'hello! ';  -- defaults to type text anyway
END
$func$ LANGUAGE plpgsql;

Es gibt andere Möglichkeiten:

  • Kann ich eine plpgsql-Funktion dazu bringen, eine Ganzzahl zurückzugeben, ohne eine Variable zu verwenden?
  • Das Handbuch zum "Zurückkehren von einer Funktion"