Eu uso o Postgresql 9.1, com o ubuntu 12.04.
Inspirado pela resposta de Craig à minha pergunta concatenação do tipo setof ou registro setof eu pensei que eu iria bem com o uso return query
, setof record
e um gerador de série para esta função plpgsql:
create or replace function compute_all_pair_by_craig(id_obj bigint)
returns setof record as $$
begin
return query select o.id, generate_series(0,o.value) from m_obj as o;
end;
$$ language plpgsql;
Durante a execução, recebo o erro:
ERROR: set_valued function called in context that cannot accept a set
O que está errado ? Ao contrário de Craig, digo à função para retornar setof record
.
Posso conseguir algo que funcione exatamente como Craig, ou seja, definindo um tipo create type pair_id_value as (idx bigint, value integer)
e fazendo com que minha função plpgsql retorne a em setof of pair_id_value
vez de a setof record
.
Mas mesmo com essa solução de trabalho, ainda não entendo por que select id, generate_series(0,13)
sozinho retornará um resultado em duas colunas ... e, ao contrário, chamar a função (retorna setof pair_id_value) com return query select id, generate_series(0,my_obj.value) from my_obj
retornará um resultado em apenas uma coluna cujo campo se pareça com este "(123123,0)" "(123123,1)" "(123123,2)" (3 linhas) que são obviamente tuplas.
É um caso em que uma tabela temporária deve / deve ser criada?
fonte
BEGIN
e- vírgula após e um ausente após oRETURN QUERY
. Depois de corrigir esses erros, confirmo o erro ao retornarrecord
; irá explicar em resposta.Respostas:
A mensagem de erro não é muito útil:
mas se você reformular a consulta para chamá-la como uma função de retorno de conjunto adequada, verá o problema real:
Se você estiver usando
SETOF RECORD
sem umaOUT
lista de parâmetros, deverá especificar os resultados na instrução de chamada, por exemplo:No entanto, é muito melhor usar
RETURNS TABLE
ouOUT
parâmetros. Com a sintaxe anterior, sua função seria:Isso pode ser chamado no contexto da lista SELECT e pode ser usado sem criar um tipo explicitamente ou especificar a estrutura de resultados no site da chamada.
Quanto à segunda metade da pergunta, o que está acontecendo é que o 1º caso especifica duas colunas separadas em uma lista SELECT, onde o segundo retorna um único composto. Na verdade, não tem a ver com o retorno do resultado, mas com a função. Se criarmos a função de amostra:
Você verá a diferença nas duas maneiras de chamar uma função de retorno de conjunto - na
SELECT
lista, uma extensão não padrão específica do PostgreSQL com comportamento peculiar:ou como uma tabela da maneira mais padrão:
fonte
returns table
.