Insertar usando una function que devuelve dos valores por fila

Esta function:

CREATE OR REPLACE FUNCTION fn_test1() RETURNS SETOF date AS $BODY$ declare i int; begin i:=0; while i<5 loop return next '2001-01-02'::date; i:=i+1; end loop; end $BODY$ LANGUAGE plpgsql VOLATILE COST 100 ROWS 1000; 

Esta table:

 CREATE TABLE teste1 ( teste1_id serial NOT NULL, num integer, fn_date date) 

Un INSERT como este funciona bien (insertando 5 filas):

 Insert into teste1(num,fn_date) select 1, fn_test1(); 

Pero si quiero tener una function que devuelva dos dates seguidas y una tabla que tenga 2 columnas de dates, ¿cómo debo hacer eso? He hecho esto hasta ahora:

 CREATE OR REPLACE FUNCTION fn_test2() RETURNS TABLE(a date, b date) AS $BODY$ declare _start_date date; _end_date date; begin _start_date:='2001-01-01'::date; _end_date:='2002-01-01'::date; i:=0; while i < 5 loop return query(select _start_date,_end_date); i:=i+1; end loop; end $BODY$ LANGUAGE plpgsql VOLATILE COST 100 ROWS 1000; 

Y esta tabla:

 CREATE TABLE teste2 ( teste2_id serial NOT NULL, num integer, start_date date, end_date date) 

Ahora, no puedo hacer esto:

 INSERT INTO teste2(num,start_date,end_date) SELECT 1, fn_test2(); 

He hecho que la function devuelva setof mytype (creando un tipo con dos dates) pero parece hacer lo mismo. ¿Cómo debo modificar la consulta INSERT o la function para que esto funcione?

Intenta usar:

 INSERT INTO teste2(num,start_date,end_date) SELECT 1, fa, fb FROM fn_test2() AS f; 

ya que ha declarado a y b como columnas de la tabla que se devuelve.

Para acceder a los campos de un tipo compuesto (bien conocido) , debe envolver el identificador entre paréntesis. Sin paréntesis, el identificador antes del punto se tomaría como un nombre de tabla según las reglas de syntax de SQL. Esto funcionaría:

 SELECT 1, (fn_test2()).* 

Por cierto, tu function ficticia podría ser más simple:

 CREATE OR REPLACE FUNCTION fn_test2() RETURNS TABLE(a date, b date) AS $func$ BEGIN a := '2001-01-01'::date; b := '2002-01-01'::date; FOR i in 0 .. 4 LOOP RETURN NEXT; END LOOP; END $func$ LANGUAGE plpgsql; 

O utilice esta simple instrucción SQL con generate_series() para el mismo efecto:

 SELECT 1, '2001-01-01'::date AS a, '2002-01-01'::date AS b FROM generate_series(0,4); 
Intereting Posts