postgresql函数 - 执行'create table ...' - 意外结果

时间:2013-10-21 16:06:59

标签: postgresql user-defined-functions plpgsql execute dynamic-sql

我正在写一个执行以下操作的函数:

使用单个字段创建临时表。 此字段是特定表中最多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;

如果我跑:         从src中选择qwert(1,x1,x2);

预期结果是表t1:

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

相反,结果是:

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

在我的代码中,行:     返回vv; 只是检查vv是否正确创建。

有人可以帮助你吗?

1 个答案:

答案 0 :(得分: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()和{的组合构建表达式{3}}。不要忘记命名列(我前面的col_sum。)。

有关string_agg()的详细信息。您可以通过这种方式传递任意数量的列。