Saltar al contenido

¿Cómo puedo devolver varias filas de registros en PL/pgSQL?

Esta es el arreglo más correcta que te podemos dar, sin embargo obsérvala detenidamente y analiza si es compatible a tu proyecto.

Solución:

La función necesita devolver un SETOF RECORD en vez de RECORD y tener uno RETURN NEXT por fila en lugar de una sola RETURNcomo en:

CREATE FUNCTION test() RETURNS SETOF RECORD AS $$
DECLARE
 rec record;
BEGIN
  select 1,2 into rec;
  return next rec;

  select 3,4 into rec;
  return next rec;
END $$ language plpgsql;

Llamador:

=> select * from test() as x(a int ,b int) ;
 a | b 
---+---
 1 | 2
 3 | 4
(2 rows)

Tenga en cuenta que SQL está tipificado fuerte y estáticamente, el RECORD pseudo-tipo es difícil de trabajar.
A menudo, es menos engorroso utilizar desde el principio un tipo compuesto con una definición completa de nombres y tipos para cada columna, ya sea con el TABLE(...) sintaxis para un tipo anónimo o con CREATE TYPE para un tipo persistente con nombre.

Usar setof record y return next rec si desea devolver varios registros de una función, ejemplo:

create or replace function test_function()
    returns setof record 
    language plpgsql as $$
declare
    rec record;
begin
    for rec in
        select i, format('str%s', i), i/2*2 = i
        from generate_series(1, 3) i
    loop
        return next rec;
    end loop;
end $$;

Dicha función debe llamarse en la cláusula FROM con una lista de definición de columna:

select test_function(); -- NO

ERROR:  set-valued function called in context that cannot accept a set  

select * from test_function();  -- NO

ERROR:  a column definition list is required for functions returning "record"

select * from test_function() as (id int, str text, is_even boolean);

 id | str  | is_even 
----+------+---------
  1 | str1 | f
  2 | str2 | t
  3 | str3 | f
(3 rows)

Una mejor opción es usar returns table(...) y return query:

drop function if exists test_function();
create or replace function test_function()
    returns table (id int, str text, is_even boolean)
    language plpgsql as $$
begin
    return query
        select i, format('str%s', i), i/2*2 = i
        from generate_series(1, 3) i;
    -- you can use return query multiple times
    -- or assign values to columns
    -- and return the row:
    id = 100;
    str = 'extra';
    is_even = true;
    return next; -- without a parameter
end $$;

Uso:

select test_function(); -- possible but rather impractical

 test_function 
---------------
 (1,str1,f)
 (2,str2,t)
 (3,str3,f)
 (100,extra,t)
(4 rows)

select * from test_function();

 id  |  str  | is_even 
-----+-------+---------
   1 | str1  | f
   2 | str2  | t
   3 | str3  | f
 100 | extra | t
(4 rows)

valoraciones y comentarios

Si entiendes que ha resultado de utilidad nuestro post, sería de mucha ayuda si lo compartes con el resto entusiastas de la programación de esta manera nos ayudas a extender este contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *