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
, wobeisome_type
kann jeder registrierte skalare oder zusammengesetzte Typ sein. -
TABLE (col1 type1, col2 type2)
- eine Ad-hoc-Zeilentypdefinition. -
SETOF record
plusOUT
Parameter zum Definieren von Spaltennamen und -typen.
100 % äquivalent zuRETURNS 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.