3

postgresqlおよび一般的に保存された関数を書くのは初めてです。入力パラメータを使用してonwを記述し、一時テーブルに格納された一連の結果を返そうとしています。私は自分の関数で次のことを行います。1)すべてのコンシューマーのリストを取得し、一時テーブルに格納されているIDを格納します。2)特定のテーブルを反復処理し、上記のリストから各値に対応する値を取得して、一時テーブルに格納します。3)一時テーブルを返します。

これが私が自分で書こうとした関数です、

create or replace function getPumps(status varchar) returns setof record as $$    (setof record?) 
DECLARE 
cons_id integer[]; 
i integer; 
temp table tmp_table;--Point B 
BEGIN 
select consumer_id into cons_id  from db_consumer_pump_details; 
 FOR i in select * from cons_id LOOP 
    select objectid,pump_id,pump_serial_id,repdate,pumpmake,db_consumer_pump_details.status,db_consumer.consumer_name,db_consumer.wenexa_id,db_consumer.rr_no into tmp_table  from db_consumer_pump_details inner join db_consumer on db_consumer.consumer_id=db_consumer_pump_details.consumer_id 
where db_consumer_pump_details.consumer_id=i and db_consumer_pump_details.status=$1--Point A 
order by db_consumer_pump_details.consumer_id,pump_id,createddate desc limit 2 
END LOOP; 
return tmp_table   
END; 
$$ 
LANGUAGE plpgsql; 

ただし、私のアプローチと、上記のコードでマークしたポイントAとBが正しいかどうかはわかりません。また、一時テーブルを作成しようとすると、大量のエラーが発生します。

編集:関数を動作させましたが、関数を実行しようとすると次のエラーが発生します。

   ERROR:  array value must start with "{" or dimension information

これが私の改訂された関数です。

 create temp table tmp_table(objectid integer,pump_id integer,pump_serial_id varchar(50),repdate timestamp with time zone,pumpmake varchar(50),status varchar(2),consumer_name varchar(50),wenexa_id varchar(50),rr_no varchar(25));

  select consumer_id into cons_id  from db_consumer_pump_details;
   FOR i in select * from cons_id LOOP
insert into tmp_table 
select objectid,pump_id,pump_serial_id,repdate,pumpmake,db_consumer_pump_details.status,db_consumer.consumer_name,db_consumer.wenexa_id,db_consumer.rr_no   from db_consumer_pump_details inner join db_consumer on db_consumer.consumer_id=db_consumer_pump_details.consumer_id where db_consumer_pump_details.consumer_id=i and db_consumer_pump_details.status=$1
order by db_consumer_pump_details.consumer_id,pump_id,createddate desc limit 2;
 END LOOP;
 return query (select * from tmp_table);
 drop table tmp_table;
  END;
  $$
  LANGUAGE plpgsql;
4

2 に答える 2

5

私の知る限り、postgres でテーブルを変数として宣言することはできません。あなたができることは、関数本体で作成し、それを徹底的に (または関数の外で) 使用することです。ただし、一時テーブルはセッションまたはコミットが終了するまで削除されないので注意してください。

行く方法は、RETURN NEXTまたはRETURN QUERYを使用することです

関数の結果の型に関しては、RETURNS TABLE の方が読みやすいことが常にわかりました。

編集: cons_id 配列は不要です。select によって返された値を繰り返すだけです。また、関数によって返された結果にクエリの結果を追加するために、1 つの関数に複数の return クエリ ステートメントを含めることもできます。

あなたの場合:

CREATE OR REPLACE FUNCTION getPumps(status varchar) 
RETURNS TABLE (objectid INTEGER,pump_id INTEGER,pump_serial_id INTEGER....)   
AS 
$$
BEGIN 
    FOR i in SELECT consumer_id FROM db_consumer_pump_details LOOP

    RETURN QUERY(
        SELECT objectid,pump_id,pump_serial_id,repdate,pumpmake,db_consumer_pump_details.status,db_consumer.consumer_name,db_consumer.wenexa_id,db_consumer.rr_no FROM db_consumer_pump_details INNER JOIN db_consumer ON db_consumer.consumer_id=db_consumer_pump_details.consumer_id 
        WHERE db_consumer_pump_details.consumer_id=i AND db_consumer_pump_details.status=$1
        ORDER BY db_consumer_pump_details.consumer_id,pump_id,createddate DESC LIMIT 2 
    );
    END LOOP;
END;
$$

編集2:

groupwise-k-maximum 問題のこのソリューションを見てみたいと思うかもしれません。これはまさにここで扱っているものです。

于 2011-11-28T13:22:33.840 に答える
0

テーブル(またはクエリ)を返す方が簡単かもしれません

CREATE FUNCTION extended_sales(p_itemno int)
RETURNS TABLE(quantity int, total numeric) AS $$
BEGIN
  RETURN QUERY SELECT quantity, quantity * price FROM sales
             WHERE itemno = p_itemno;
END;
$$ LANGUAGE plpgsql;

( postgresql docsからコピー)

于 2011-11-28T13:22:13.923 に答える