Ответ 1
Попробуйте использовать:
INSERT INTO teste2(num,start_date,end_date)
SELECT 1, f.a, f.b FROM fn_test2() AS f;
так как вы объявили a и b как столбцы возвращаемой таблицы.
Эта функция:
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;
Эта таблица:
CREATE TABLE teste1
(
teste1_id serial NOT NULL,
num integer,
fn_date date)
INSERT, как это, прекрасно работает (вставка 5 строк):
Insert into teste1(num,fn_date)
select 1, fn_test1();
Но если я хочу иметь функцию, которая возвращает две даты в строке и таблицу с двумя столбцами дат, как мне это сделать? Я сделал это до сих пор:
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;
И эта таблица:
CREATE TABLE teste2
(
teste2_id serial NOT NULL,
num integer,
start_date date,
end_date date)
Теперь я не могу этого сделать:
INSERT INTO teste2(num,start_date,end_date)
SELECT 1, fn_test2();
Я сделал функцию return setof mytype
(создавая тип с двумя датами), но, похоже, делает то же самое.
Как мне изменить запрос INSERT или функцию, чтобы сделать эту работу?
Попробуйте использовать:
INSERT INTO teste2(num,start_date,end_date)
SELECT 1, f.a, f.b FROM fn_test2() AS f;
так как вы объявили a и b как столбцы возвращаемой таблицы.
В поля доступа (хорошо известного) составного типа, вам нужно обернуть идентификатор в круглые скобки. Без скобок идентификатор перед точкой будет считаться именем таблицы для синтаксических правил SQL. Это будет работать:
SELECT 1, (fn_test2()).*
Кстати, ваша фиктивная функция может быть проще:
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;
Или используйте этот простой оператор SQL с generate_series()
с тем же эффектом:
SELECT 1, '2001-01-01'::date AS a, '2002-01-01'::date AS b
FROM generate_series(0,4);