Yo uso Postgresql 9.1, con ubuntu 12.04.
Inspirado por la respuesta de Craig a mi pregunta concatenación de tipo setof o registro setof pensé que iba a ir bien con el uso return query
, setof record
y un generador de serie en esta función 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 la ejecución me sale el error:
ERROR: set_valued function called in context that cannot accept a set
Qué está mal ? Al contrario de Craig, le digo a la función que regrese setof record
.
Puedo lograr algo que funcione haciendo exactamente como Craig, es decir, definiendo un tipo create type pair_id_value as (idx bigint, value integer)
y haciendo que mi función plpgsql devuelva a en setof of pair_id_value
lugar de a setof record
.
Pero incluso con esta solución de trabajo, todavía no entiendo por qué select id, generate_series(0,13)
solo devolverá un resultado en dos columnas ... y, por el contrario, llamar a la función (devuelve setof pair_id_value) con return query select id, generate_series(0,my_obj.value) from my_obj
devolverá un resultado en solo una columna cuyo campo se parece esto "(123123,0)" "(123123,1)" "(123123,2)" (3 filas) que obviamente son tuplas.
¿Es un caso donde se debe / se debe crear una tabla temporal?
fuente
BEGIN
y coma en exceso después y uno que falta después delRETURN QUERY
. Después de corregir esos errores, confirmo el error al regresarrecord
; explicará en respuesta.Respuestas:
El mensaje de error no es muy útil:
pero si reformula la consulta para llamarla como una función de devolución de conjuntos adecuada, verá el verdadero problema:
Si utiliza
SETOF RECORD
sin unaOUT
lista de parámetros, debe especificar los resultados en la declaración de llamada, por ejemplo:Sin embargo, es mucho mejor usar
RETURNS TABLE
oOUT
parámetros. Con la sintaxis anterior, su función sería:Esto se puede llamar en el contexto de la lista SELECT y se puede usar sin crear un tipo explícitamente o sin especificar la estructura de resultados en el sitio de la llamada.
En cuanto a la segunda mitad de la pregunta, lo que sucede es que el primer caso especifica dos columnas separadas en una lista SELECT, mientras que el segundo devuelve un único compuesto. En realidad, no tiene que ver con cómo está devolviendo el resultado, sino cómo está invocando la función. Si creamos la función de muestra:
Verá la diferencia en las dos formas de llamar a una función de retorno de conjunto: en la
SELECT
lista, una extensión no estándar específica de PostgreSQL con un comportamiento peculiar:o como una tabla de la manera más estándar:
fuente
returns table
.