0

私は次のことを行う関数を書いています:

単一のフィールドを持つ一時テーブルを作成します。このフィールドは、特定のテーブルから最大 5 つの変数を合計した結果です。

次のテーブルがあるとします。

create table src (x1 numeric, x2 numeric);
insert into src values (2,1),(5,2),(10,4);

私のコードは次のとおりです。

create or replace function qwert(cod numeric, v1 numeric default 0
    , v2 numeric default 0, v3 numeric default 0, v4 numeric default 0,
    v5 numeric default 0)
returns numeric as
$func$
declare vv numeric;
begin
vv = v1+v2+v3+v4+v5;
execute '
    drop table if exists t' || cod || '; 
    create temporary table t' || cod || ' as 
    select ' || vv || ' ;'
    ;
return vv;
end
$func$ language plpgsql;

実行した場合: select qwert(1, x1,x2) from src;

期待される結果はテーブル t1 です。

 column1 
---------
       3
       7
       14
(3 rows)

代わりに、結果は次のとおりです。

db1=# select * from t1;
 ?column? 
----------
       14
(1 row)

私のコードでは、行:return vv; vv が正しく作成されたかどうかを確認するためだけに存在します。

誰かがこれを手伝ってくれますか?

4

1 に答える 1

1

次のように機能します。

CREATE OR REPLACE FUNCTION qwert(_tbl text, cols text[])
  RETURNS numeric AS
$func$
BEGIN

EXECUTE format('
     DROP TABLE IF EXISTS %1$I;
     CREATE TEMPORARY TABLE %1$I AS 
     SELECT %2$s AS col_sum FROM src;'
   ,_tbl
   ,(SELECT string_agg(quote_ident(i), ' + ') FROM unnest(cols) i)
    );

RETURN 1;  -- still unclear? Add yourself ...
END
$func$ LANGUAGE PLPGSQL;

電話:

SELECT qwert('t1', ARRAY['x1','x2']);

または:

SELECT qwert('t1', '{x1,x2}');

format()Postgres 9.1 以降が必要です。

text一時テーブル名にパラメーターを使用し、列名に を使用してから、とarray of textの組み合わせで式を作成します。列に名前を付けることを忘れないでください(私の例では)。unnest()quote_ident()string_agg()col_sum

dba.SE のこの関連する回答で、識別子として使用するのサニタイズに関する詳細。この方法で任意の数の列を渡すことができます。

于 2013-10-21T16:40:19.853 に答える