Du blander syntaksen for at returnere SETOF
værdier med syntaks til at returnere en enkelt række eller værdi.
-- Et relateret spørgsmål er - hvordan returnerer jeg den enkelte post 'r' fra
Når du erklærer en funktion med RETURNS TABLE
, skal du bruge RETURN NEXT
i kroppen for at returnere en række (eller skalarværdi). Og hvis du vil bruge en record
variabel med, at den skal matche returtypen. Se kodeeksemplerne længere nede.
Returner en enkelt værdi eller række
Hvis du blot ønsker at returnere en enkelt række, er der intet behov for en post af udefineret type. @Kevin har allerede demonstreret to måder. Jeg tilføjer en forenklet version med OUT
parametre:
CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
AS
$func$
BEGIN
a := ...;
b := ...;
END
$func$ LANGUAGE plpgsql;
Du behøver ikke engang at tilføje RETURN;
i funktionsteksten, værdien af den erklærede OUT
parametre vil blive returneret automatisk i slutningen af funktionen - NULL
for enhver parameter, der ikke er blevet tildelt.
Og du behøver ikke at erklære RETURNS RECORD
fordi det allerede er klart fra OUT
parametre.
Returner et sæt rækker
Hvis du rent faktisk ønsker at returnere flere rækker (inklusive muligheden for 0 eller 1 række), kan du definere returtypen som RETURNS
...
-
SETOF some_type
, hvorsome_type
kan være enhver registreret skalær eller sammensat type. -
TABLE (col1 type1, col2 type2)
- en ad-hoc rækketypedefinition. -
SETOF record
plusOUT
parametre til at definere kolonnenavne og -typer.
100 % svarende tilRETURNS TABLE
. -
SETOF record
uden nærmere definition. Men så er de returnerede rækker udefinerede og du skal inkludere en kolonnedefinitionsliste med hvert opkald (se eksempel).
Manualen om posttypen:
Postvariabler ligner rækkevariabler, men de har ingen foruddefineret struktur. De overtager den faktiske rækkestruktur af den række, de er tildelt under en SELECT- eller FOR-kommando.
Der er mere, læs manualen.
Du kan bruge en registreringsvariabel uden at tildele en defineret type, du kan endda returnere sådanne udefinerede poster:
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;
Ring til:
SELECT * FROM my_func() AS x(a int, b text);
Men dette er meget uhåndterligt da du skal angive kolonnedefinitionslisten ved hvert opkald. Det kan generelt erstattes med noget mere elegant:
- Hvis du kender typen på tidspunktet for funktionsoprettelse, skal du deklarere den med det samme (
RETURNS TABLE
eller venner).
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;
- Hvis du kender typen på tidspunktet for funktionskaldet , der er mere elegante måder at bruge polymorfe typer:
Refaktorer en PL/pgSQL-funktion for at returnere output fra forskellige SELECT-forespørgsler
Dit spørgsmål er uklart med hensyn til, hvad du præcist har brug for.