Você está misturando a sintaxe para retornar
SETOF
valores com sintaxe para retornar uma única linha ou valor.
-- Uma questão relacionada é - como faço para retornar o registro único 'r' de
Quando você declara uma função com
RETURNS TABLE
, você deve usar RETURN NEXT
no corpo para retornar uma linha (ou valor escalar). E se você quiser usar um record
variável com a qual tem que corresponder o tipo de retorno. Consulte os exemplos de código mais abaixo. Retorne um único valor ou linha
Se você deseja retornar apenas uma única linha, não há necessidade para um registro de tipo indefinido. @Kevin já demonstrou duas maneiras. Vou adicionar uma versão simplificada com
OUT
parâmetros:CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
AS
$func$
BEGIN
a := ...;
b := ...;
END
$func$ LANGUAGE plpgsql;
Você nem precisa adicionar
RETURN;
no corpo da função, o valor do OUT
declarado parâmetros serão retornados automaticamente no final da função - NULL
para qualquer parâmetro que não tenha sido atribuído.E você não precisa declarar
RETURNS RECORD
porque isso já está claro no OUT
parâmetros. Retorne um conjunto de linhas
Se você realmente deseja retornar múltiplos linhas (incluindo a possibilidade de 0 ou 1 linha), você pode definir o tipo de retorno como
RETURNS
... -
SETOF some_type
, ondesome_type
pode ser qualquer tipo escalar ou composto registrado.
-
TABLE (col1 type1, col2 type2)
- uma definição de tipo de linha ad hoc.
-
SETOF record
maisOUT
parâmetros para definir nomes e tipos de coluna.
100% equivalente aRETURNS TABLE
.
-
SETOF record
sem mais definição. Mas as linhas retornadas são indefinidas e você precisa incluir uma lista de definição de coluna com cada chamada (veja o exemplo).
O manual sobre o tipo de registro:
As variáveis de registro são semelhantes às variáveis do tipo linha, mas não têm estrutura predefinida. Eles assumem a estrutura de linha real da linha atribuída durante um comando SELECT ou FOR.
Há mais, leia o manual.
Você pode usar uma variável de registro sem atribuir um tipo definido, você pode até mesmo retornar esses registros indefinidos:
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;
Ligar:
SELECT * FROM my_func() AS x(a int, b text);
Mas isso é muito complicado pois você precisa fornecer a lista de definição de coluna com cada chamada. Geralmente pode ser substituído por algo mais elegante:
- Se você souber o tipo no momento da criação da função, declare-o imediatamente (
RETURNS TABLE
ou amigos).
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;
- Se você souber o tipo no momento da chamada da função , existem maneiras mais elegantes de usar tipos polimórficos:
Refatorar uma função PL/pgSQL para retornar a saída de várias consultas SELECT
Sua pergunta não está clara quanto ao que você precisa exatamente.