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

Deklarieren der Tupelstruktur eines Datensatzes in PL/pgSQL

Sie mischen die Syntax für die Rückgabe von SETOF Werte mit Syntax zum Zurückgeben einer einzelnen Zeile oder eines Werts.

-- Eine verwandte Frage ist - wie gebe ich den einzelnen Datensatz 'r' von

zurück

Wenn Sie eine Funktion mit RETURNS TABLE deklarieren , müssen Sie RETURN NEXT verwenden im Körper, um eine Zeile (oder einen Skalarwert) zurückzugeben. Und wenn Sie einen record verwenden möchten Variable, mit der sie übereinstimmen muss der Rückgabetyp. Siehe die Codebeispiele weiter unten.

Gib einen einzelnen Wert oder eine Zeile zurück

Wenn Sie nur eine einzelne Zeile zurückgeben möchten, besteht keine Notwendigkeit für einen Datensatz eines undefinierten Typs. @Kevin hat bereits zwei Möglichkeiten demonstriert. Ich werde eine vereinfachte Version mit OUT hinzufügen Parameter:

CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
   AS
$func$
BEGIN
   a := ...;
   b := ...;
END
$func$ LANGUAGE plpgsql;

Sie müssen nicht einmal RETURN; hinzufügen im Funktionsrumpf der Wert des deklarierten OUT Parameter werden automatisch am Ende der Funktion zurückgegeben - NULL für jeden Parameter, der nicht zugewiesen wurde.
Und Sie müssen RETURNS RECORD nicht deklarieren denn das geht schon aus dem OUT hervor Parameter.

Eine Reihe von Zeilen zurückgeben

Wenn Sie tatsächlich mehrere zurückgeben möchten Zeilen (einschließlich der Möglichkeit für 0 oder 1 Zeile) können Sie den Rückgabetyp als RETURNS definieren ...

  • SETOF some_type , wobei some_type kann jeder registrierte skalare oder zusammengesetzte Typ sein.

  • TABLE (col1 type1, col2 type2) - eine Ad-hoc-Zeilentypdefinition.

  • SETOF record plus OUT Parameter zum Definieren von Spaltennamen und -typen.
    100 % äquivalent zu RETURNS TABLE .

  • SETOF record ohne weitere Definition. Aber dann sind die zurückgegebenen Zeilen undefiniert und Sie müssen bei jedem Aufruf eine Spaltendefinitionsliste einbinden (siehe Beispiel).

Das Handbuch zum Datensatztyp:

Datensatzvariablen ähneln zeilenartigen Variablen, aber sie haben keine vordefinierte Struktur. Sie nehmen die tatsächliche Zeilenstruktur der Zeile an, die ihnen während eines SELECT- oder FOR-Befehls zugewiesen wird.

Es gibt noch mehr, lesen das Handbuch.

Sie können eine Datensatzvariable verwenden, ohne einen definierten Typ zuzuweisen, können Sie gibt sogar solche undefinierten Datensätze zurück:

CREATE OR REPLACE FUNCTION my_func()
  RETURNS SETOF record AS
$func$
DECLARE
    r record;
BEGIN
    r := (1::int, 'foo'::text); RETURN NEXT r; -- works with undefined record
    r := (2::int, 'bar'::text); RETURN NEXT r;
END
$func$ LANGUAGE plpgsql;

Aufruf:

SELECT * FROM my_func() AS x(a int, b text);

Aber das ist sehr unhandlich da Sie die Spaltendefinitionsliste bei jedem Aufruf bereitstellen müssen. Es kann im Allgemeinen durch etwas Eleganteres ersetzt werden:

  • Wenn Sie den Typ zum Zeitpunkt der Funktionserstellung kennen, deklarieren Sie ihn sofort (RETURNS TABLE oder Freunde).

CREATE OR REPLACE FUNCTION my_func()
  RETURNS SETOF tbl_or_type AS
$func$
DECLARE
    r tbl_or_type;
BEGIN
    SELECT INTO tbl_or_type  * FROM tbl WHERE id = 10;
    RETURN NEXT r;  -- type matches

    SELECT INTO tbl_or_type  * FROM tbl WHERE id = 12;
    RETURN NEXT r;

    -- Or simpler:
    RETURN QUERY
    SELECT * FROM tbl WHERE id = 14;
END
$func$ LANGUAGE plpgsql;
  • Wenn Sie den Typ zum Zeitpunkt des Funktionsaufrufs kennen , gibt es elegantere Möglichkeiten, polymorphe Typen zu verwenden:
    Refaktorisieren Sie eine PL/pgSQL-Funktion, um die Ausgabe verschiedener SELECT-Abfragen zurückzugeben

Ihre Frage ist unklar, was Sie genau brauchen.