PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Maneira fácil de ter o tipo de retorno como tabela SETOF mais campos adicionais?


Você poderia retorne uma linha inteira como tipo composto e adicione mais:
CREATE OR REPLACE FUNCTION f_rowplus()
  RETURNS TABLE (rec demo, add_int int, add_txt text) AS
$func$
SELECT d, 5, 'baz'::text FROM demo d;
$func$  LANGUAGE sql;

Mas então, quando você usa a chamada simples:
SELECT * FROM f_rowplus();

Você obtém a linha da tabela demo como tipo composto separado. Você teria que ligar:
SELECT (rec).*,  add_int, add_txt FROM f_rowplus();

para obter todos os individuais colunas. Parênteses obrigatórios.

Postgres é um pouco inconsistente aqui. Se você criar uma função com:
CREATE OR REPLACE FUNCTION f_row2()
  RETURNS TABLE (rec demo) AS
...

então o tipo composto demo é silenciosamente convertido em colunas individuais (decompostas). Nenhum link para o tipo composto original permanece. Você não pode fazer referência à coluna de saída declarada rec nada, uma vez que foi substituído pelas colunas do tipo decomposto. Essa chamada resultaria em uma mensagem de erro:
SELECT rec FROM f_row2();

Mesmo aqui:
CREATE OR REPLACE FUNCTION f_row3(OUT rec demo)
  RETURNS SETOF demo AS
...

No entanto , assim que você adicionar qualquer mais OUT colunas, o tipo composto é preservado como declarado (não decomposto) e você pode:
SELECT rec FROM f_rowplus();

com a primeira função.

Eu criei um SQL Fiddle demonstrando as variantes.

À parte
Ao usar uma função retornando várias colunas no FROM list (como função de tabela) e decompondo no SELECT lista assim:
SELECT (rec).* FROM f_rowplus();

... a função ainda é avaliada uma vez apenas - enquanto uma chamada e decompondo no SELECT list diretamente assim:
SELECT (f_rowplus()).*;  -- also: different result

... avaliaria uma vez para cada coluna no tipo de retorno. Detalhes: