it-swarm.com.de

Unterschied zwischen Sprache SQL und Sprache plpgsql in PostgreSQL-Funktionen

Ich bin sehr neu in Datenbankentwicklung, daher habe ich einige Zweifel an meinem folgenden Beispiel:

Funktion f1 () -sprache sql

 create or replace function f1(istr  varchar) returns text as $$ 
 select 'hello! '::varchar || istr;
 $$ language sql;

Funktion f2 () -Sprache plpgsql

 create  or replace function f2(istr  varchar)
 returns text as $$ 
 begin select 'hello! '::varchar || istr; end;
 $$ language plpgsql;
  • Beide funktionen können wie select f1('world') oder select f2('world') aufgerufen werden.

  • Wenn ich select f1('world') anrufe, wird die output sein:

    `hello! world`
    
  • Und output für select f2('world'):

    FEHLER: Abfrage hat kein Ziel für Ergebnisdaten TIPP: Wenn Sie die Ergebnisse eines SELECT verwerfen möchten, verwenden Sie stattdessen PERFORM . CONTEXT: PL/pgSQL-Funktion f11 (Zeichenänderung) Zeile 2 bei SQL-Anweisung ****** Error ******

  • Ich möchte den Unterschied erfahren und in welchen Situationen ich language sql oder language plpgsql verwenden sollte.

Nützliche Links oder Antworten zu Funktionen werden sehr geschätzt.

28
user3814846

SQL-Funktionen

sind die bessere Wahl:

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

  • Für Einzelaufrufe pro Sitzung. Von der Zwischenspeicherung von Plänen und vorbereiteten 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 sein.

  • Aus Mangel an Erfahrung mit jeder Verfahrenssprache wie PL/pgSQL. Viele kennen SQL gut und das ist alles, was Sie für SQL-Funktionen benötigen. Nur wenige können dasselbe über PL/pgSQL sagen.

  • Ein bisschen kürzerer Code. Kein Blockaufwand.

PL/pgSQL-Funktionen

sind die bessere Wahl:

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

  • Für jede Art von dynamisches SQL, wo Sie dynamisch und EXECUTE Anweisungen erstellen. Besondere Vorsicht ist geboten, um die SQL-Injection zu vermeiden. Mehr Details:

  • Wenn Sie Berechnungen haben, kann wiederverwendet an mehreren Stellen vorhanden sein, und ein CTE kann zu diesem Zweck nicht gedehnt werden. In einer SQL-Funktion haben Sie keine Variablen und würden gezwungen sein, wiederholt zu berechnen oder in eine Tabelle zu schreiben. Diese verwandte Antwort auf dba.SE enthält nebeneinander liegende Codebeispiele, um dasselbe Problem mithilfe einer SQL-Funktion/einer plpgsql-Funktion/einer Abfrage mit CTEs zu lösen:

    Aufträge sind etwas teurer als in anderen Verfahrenssprachen. Passen Sie einen Programmierstil an, der nicht mehr als nötig benötigt.

  • Wenn eine Funktion nicht eingebettet werden kann und wiederholt aufgerufen wird. Anders als bei SQL-Funktionen kann Abfragepläne können zwischengespeichert werden für alle SQL-Anweisungen innerhalb einer PL/pgSQL-Funktion ; Sie werden wie Prepared Statements behandelt, der Plan wird für wiederholte Aufrufe in derselben Sitzung zwischengespeichert (wenn Postgres erwartet, dass der zwischengespeicherte (generische) Plan eine bessere Leistung als jedes Mal eine Neuplanung durchführt.) pgSQL-Funktionen sind in diesen Fällen nach den ersten paar Aufrufen normalerweise schneller

    Hier ist ein Thread zum Thema pgsql-performance, in dem einige dieser Punkte behandelt werden:
    Re: pl/pgsql-Funktionen übertreffen SQL-Funktionen?

  • Wenn Sie Fehler auffangen müssen.

  • Für Auslöseprozeduren (was auch nur Funktionen sind).

  • Beim Einfügen von DDL-Anweisungen ändern Sie Objekte oder ändern Systemkataloge in einer für nachfolgende Befehle relevanten Weise, da alle Anweisungen in SQL-Funktionen gleichzeitig analysiert werden, während PL/pgSQL-Funktionen jede Anweisung nacheinander (wie eine vorbereitete Anweisung) planen und ausführen. Sehen:

Bedenken Sie auch:


Der Vollständigkeit halber: Um tatsächlich von einer PL/pgSQL-Funktion return zurückzugeben, können 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:

41

PL/PgSQL ist eine PostgreSQL-spezifische prozedurale Sprache, die auf SQL basiert. Es hat Schleifen, Variablen, Fehler-/Ausnahmebehandlung usw. Nicht alle SQL-Werte sind PL/PgSQL. Wie Sie festgestellt haben, können Sie SELECT nicht ohne INTO oder RETURN QUERY verwenden. PL/PgSQL kann auch in DO-Blöcken für One-Shot-Prozeduren verwendet werden.

sql-Funktionen kann nur reines SQL verwenden, sie sind jedoch oft effizienter und einfacher zu schreiben, da Sie keinen BEGIN ... END;-Block benötigen/PgSQL.

Menschen verwenden oft PL/PgSQL, wo reines SQL ausreicht, weil sie daran gewöhnt sind, prozessual zu denken. In den meisten Fällen, wenn Sie der Meinung sind, dass Sie PL/PgSQL benötigen, ist dies wahrscheinlich nicht der Fall. Rekursive CTEs, Querabfragen usw. erfüllen im Allgemeinen die meisten Anforderungen.

Weitere Informationen finden Sie im Handbuch.

13
Craig Ringer

nehmen Sie einfach die Auswahlabfrage vor, die Sie innerhalb der Funktion als Rückgabewert geschrieben haben:

 create  or replace function f2(istr  varchar)
 returns text as $$ 
 begin return(select 'hello! '::varchar || istr); end;
 $$ language plpgsql;
0
ZORRO_BLANCO