3

この機能:

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 つの日付を連続して返す関数と、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た(2つの日付を持つ型を作成します)が、同じことをしているようです。これを機能させるには、INSERT クエリまたは関数をどのように変更すればよいですか?

4

2 に答える 2

2

(よく知られている) 複合型のフィールドにアクセスするには、識別子を括弧で囲む必要があります。括弧がないと、ドットの前の識別子が 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);
于 2013-02-19T21:18:51.473 に答える
1

使用してみてください:

INSERT INTO teste2(num,start_date,end_date)
SELECT 1, f.a, f.b FROM fn_test2() AS f;

返されるテーブルの列として a と b を宣言したためです。

于 2013-02-19T19:56:50.010 に答える