sql >> Base de Datos >  >> RDS >> PostgreSQL

Declarar la estructura de tupla de un registro en PL/pgSQL

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 , donde some_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ás OUT parámetros para definir nombres y tipos de columnas.
    100% equivalente a RETURNS 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.