此功能:
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();
但是,如果我想要一个连续返回两个日期的函数,并且有一个包含2列日期的表,我应该怎么做?到目前为止我已经做到了这一点:
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();
我已经使函数返回setof mytype
(创建一个带有两个日期的类型),但它似乎做了同样的事情。
我应该如何修改INSERT查询或函数来使其工作?
答案 0 :(得分:2)
要access fields of a (well known) composite type,您需要将标识符包装在括号中。如果没有括号,则点之前的标识符将被视为每个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;
或者使用这个带有generate_series()
的简单SQL语句来达到同样的效果:
SELECT 1, '2001-01-01'::date AS a, '2002-01-01'::date AS b
FROM generate_series(0,4);
答案 1 :(得分:1)
尝试使用:
INSERT INTO teste2(num,start_date,end_date)
SELECT 1, f.a, f.b FROM fn_test2() AS f;
因为您已将a和b声明为要返回的表的列。