Está mezclando la sintaxis para devolver SETOF
valores con sintaxis para devolver una sola fila o valor.
-- Una pregunta relacionada es:¿cómo devuelvo el registro único 'r' de
?
Cuando declaras una función con RETURNS TABLE
, tienes que usar RETURN NEXT
en el cuerpo para devolver una fila (o valor escalar). Y si quieres usar un record
variable con la que tiene que coincidir el tipo de retorno. Consulte los ejemplos de código más abajo.
Retorna un solo valor o fila
Si solo desea devolver una sola fila, no es necesario para un registro de tipo indefinido. @Kevin ya demostró dos formas. Agregaré una versión simplificada con OUT
parámetros:
CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
AS
$func$
BEGIN
a := ...;
b := ...;
END
$func$ LANGUAGE plpgsql;
Ni siquiera necesita agregar RETURN;
en el cuerpo de la función, el valor del OUT
declarado los parámetros se devolverán automáticamente al final de la función - NULL
para cualquier parámetro que no haya sido asignado.
Y no necesita declarar RETURNS RECORD
porque eso ya está claro desde el OUT
parámetros.
Devolver un conjunto de filas
Si realmente desea devolver múltiples filas (incluida la posibilidad de 0 o 1 fila), puede definir el tipo de devolución como RETURNS
...
-
SETOF some_type
, dondesome_type
puede ser cualquier tipo escalar o compuesto registrado. -
TABLE (col1 type1, col2 type2)
- una definición de tipo de fila ad-hoc. -
SETOF record
másOUT
parámetros para definir nombres y tipos de columnas.
100% equivalente aRETURNS TABLE
. -
SETOF record
sin mayor definición. Pero luego las filas devueltas son indefinidas y debe incluir una lista de definición de columna con cada llamada (ver ejemplo).
El manual sobre el tipo de registro:
Las variables de registro son similares a las variables de tipo fila, pero tienen una estructura predefinida. Adoptan la estructura de fila real de la fila que se les asigna durante un comando SELECT o FOR.
Hay más, leer el manual.
Tu puedes usar una variable de registro sin asignar un tipo definido, puede incluso devolver tales registros no definidos:
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;
Llamar:
SELECT * FROM my_func() AS x(a int, b text);
Pero esto es muy difícil de manejar ya que debe proporcionar la lista de definición de columna con cada llamada. Generalmente se puede reemplazar con algo más elegante:
- Si conoce el tipo en el momento de la creación de la función, declárelo de inmediato (
RETURNS TABLE
o 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;
- Si conoce el tipo en el momento de la llamada de función , hay formas más elegantes de usar tipos polimórficos:
Refactorizar una función PL/pgSQL para devolver el resultado de varias consultas SELECT
Su pregunta no está clara en cuanto a lo que necesita exactamente.