Смесвате синтаксиса за връщане на SETOF
стойности със синтаксис за връщане на един ред или стойност.
-- Свързан въпрос е - как да върна единичния запис 'r' от
Когато декларирате функция с RETURNS TABLE
, трябва да използвате RETURN NEXT
в тялото, за да върне ред (или скаларна стойност). И ако искате да използвате record
променлива, с която трябва да съвпада типът връщане. Вижте примерите за код по-долу.
Връщане на единична стойност или ред
Ако искате да върнете само един ред, няма нужда за запис от недефиниран тип. @Kevin вече демонстрира два начина. Ще добавя опростена версия с OUT
параметри:
CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
AS
$func$
BEGIN
a := ...;
b := ...;
END
$func$ LANGUAGE plpgsql;
Дори не е нужно да добавяте RETURN;
в тялото на функцията, стойността на декларирания OUT
параметрите ще бъдат върнати автоматично в края на функцията - NULL
за всеки параметър, който не е бил присвоен.
И не е нужно да декларирате RETURNS RECORD
защото това вече е ясно от OUT
параметри.
Връщане на набор от редове
Ако всъщност искате да върнете множество редове (включително възможността за 0 или 1 ред), можете да дефинирате типа на връщане като RETURNS
...
-
SETOF some_type
, къдетоsome_type
може да бъде всеки регистриран скаларен или композитен тип. -
TABLE (col1 type1, col2 type2)
- ad hoc определение на типа ред. -
SETOF record
плюсOUT
параметри за дефиниране на имена и типове на колони.
100% еквивалент наRETURNS TABLE
. -
SETOF record
без допълнително определение. Но след това върнатите редове са недефинирани и трябва да включите списък с дефиниции на колони с всяко извикване (вижте примера).
Ръководството за типа на записа:
Променливите за запис са подобни на променливите от редов тип, но имат без предварително дефинирана структура. Те поемат действителната структура на реда на реда, който им е присвоен по време на команда SELECT или FOR.
Има още, прочетете ръководството.
Вие можете използвайте променлива на запис, без да присвоявате дефиниран тип, можете дори да върне такива недефинирани записи:
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;
Обадете се:
SELECT * FROM my_func() AS x(a int, b text);
Но това е много тромаво тъй като трябва да предоставяте списъка с дефиниции на колони при всяко повикване. По принцип може да бъде заменен с нещо по-елегантно:
- Ако знаете типа към момента на създаване на функцията, декларирайте го веднага (
RETURNS TABLE
или приятели).
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;
- Ако знаете типа в момента на извикването на функция , има по-елегантни начини за използване на полиморфни типове:
Рефакторирайте функция PL/pgSQL, за да върнете резултатите от различни SELECT заявки
Въпросът ви не е ясен какво точно ви трябва.