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_typepuede ser cualquier tipo escalar o compuesto registrado. -
TABLE (col1 type1, col2 type2)- una definición de tipo de fila ad-hoc. -
SETOF recordmásOUTparámetros para definir nombres y tipos de columnas.
100% equivalente aRETURNS TABLE. -
SETOF recordsin 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 TABLEo 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.