Mieszasz składnię zwracania SETOF
wartości ze składnią do zwracania pojedynczego wiersza lub wartości.
-- Pokrewnym pytaniem jest - jak zwrócić pojedynczy rekord „r” z
Kiedy deklarujesz funkcję za pomocą RETURNS TABLE
, musisz użyć RETURN NEXT
w ciele, aby zwrócić wiersz (lub wartość skalarną). A jeśli chcesz użyć record
zmienna z którą musi pasować typ zwrotu. Zapoznaj się z przykładami kodu poniżej.
Zwróć pojedynczą wartość lub wiersz
Jeśli chcesz zwrócić tylko jeden wiersz, nie ma potrzeby dla rekordu nieokreślonego typu. @Kevin już zademonstrował dwa sposoby. Dodam uproszczoną wersję z OUT
parametry:
CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
AS
$func$
BEGIN
a := ...;
b := ...;
END
$func$ LANGUAGE plpgsql;
Nie musisz nawet dodawać RETURN;
w ciele funkcji wartość zadeklarowanego OUT
parametry zostaną zwrócone automatycznie na końcu funkcji - NULL
dla dowolnego parametru, który nie został przypisany.
I nie musisz deklarować RETURNS RECORD
ponieważ jest to już jasne z OUT
parametry.
Zwróć zestaw wierszy
Jeśli rzeczywiście chcesz zwrócić wiele wierszy (w tym możliwość 0 lub 1 wiersza), możesz zdefiniować typ zwrotu jako RETURNS
...
-
SETOF some_type
, gdziesome_type
może być dowolnym zarejestrowanym typem skalarnym lub złożonym. -
TABLE (col1 type1, col2 type2)
- definicja typu wiersza ad-hoc. -
SETOF record
plusOUT
parametry do definiowania nazw i typów kolumn.
100% odpowiednikRETURNS TABLE
. -
SETOF record
bez dalszej definicji. Ale wtedy zwrócone wiersze są niezdefiniowane i musisz dołączyć listę definicji kolumn do każdego wywołania (patrz przykład).
Instrukcja o typie rekordu:
Zmienne rekordów są podobne do zmiennych typu wierszowego, ale mają niepredefiniowaną strukturę Przyjmują one rzeczywistą strukturę wiersza, do którego są przypisane podczas polecenia SELECT lub FOR.
Jest więcej, przeczytaj instrukcja.
możesz użyć zmiennej rekordu bez przypisywania określonego typu, możesz nawet zwrócić takie niezdefiniowane rekordy:
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;
Zadzwoń:
SELECT * FROM my_func() AS x(a int, b text);
Ale to jest bardzo nieporęczne ponieważ przy każdym wywołaniu musisz podać listę definicji kolumn. Ogólnie można go zastąpić czymś bardziej eleganckim:
- Jeśli znasz typ w momencie tworzenia funkcji, zadeklaruj go od razu (
RETURNS TABLE
lub znajomych).
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;
- Jeśli znasz typ w momencie wywołania funkcji , istnieją bardziej eleganckie sposoby używania typów polimorficznych:
Refaktoryzacja funkcji PL/pgSQL w celu zwrócenia danych wyjściowych różnych zapytań SELECT
Twoje pytanie nie jest jasne, czego dokładnie potrzebujesz.