Postgres如何评估查询中的表达式到函数中的变量

时间:2012-09-06 09:15:04

标签: postgresql dynamic execute plpgsql evaluation

我希望能够获取从表中查询其名称的函数变量的值

编辑显示查询表而不是查询静态值:

    create table __test__
(
_col text
);
insert into __test__
(_col)
values('_a');

   create or replace function __test() 
    returns void
    language 'plpgsql' as
    $$
    declare
      _r record;
      _a int;
      _b int;
      _sql text;
    begin

      _a = 1;
      _b = 0;

      for _r in select _col as _nam from __test__ a loop
      -- query returns one row valued "_a"
        _sql = 'select ' || _r._nam ;
        execute _sql into _b;
      end loop;

      raise info 'value of _b %', _b;

    end;
    $$;
select __test()

当函数执行时_b = 1.是否可以?

同样的错误......

ERROR:  column "_a" does not exist
LINE 1: select _a
               ^
QUERY:  select _a
CONTEXT:  PL/pgSQL function "__test" line 15 at EXECUTE statement

2 个答案:

答案 0 :(得分:2)

您可以创建一个临时表,在其中插入变量名称和值,然后对其执行选择。干净后再清理一下。我曾经使用过类似的方法。它工作正常。它确实有额外的开销。

编辑:添加示例

CREATE FUNCTION switch (in_var text) RETURNS text
LANGUAGE PLPGSQL VOLATILE AS $$

declare t_test text;
    switch_vals text[];

BEGIN

   CREATE TEMPORARY TABLE switch_values (var text, value text);

   EXECUTE $e$ INSERT INTO switch_values VALUES 
       ('a', '1'), ('b', '2'), ('c', '3') $e$;

   EXECUTE $e$ SELECT value FROM switch_values WHERE var = $e$ || quote_literal(in_var)
       INTO t_test;

   DROP TABLE switch_values;

   RETURN t_test;

END; $$; 

postgres=# select switch('a');
  switch 
 --------
   1
 (1 row)

答案 1 :(得分:1)

让我们尝试重新构建问题:您之后的内容将等同于Perl eval() 函数,具有执行动态生成的代码段的能力,其中任何外部词汇变量都可以看到"。在您的示例中,变量将是_a,但是从错误消息中可以看出,它不能通过动态SQL语句进行插值。原因是SQL解释器对当前的pl / pgsql变量没有可见性,甚至不知道存在这些变量。它们仅限于pl / pgsql。

这里需要的是一个上下文感知的动态生成的pl / pgsql语句,但是这种语言没有这个功能。如果没有这个功能,可以找到一个技巧来实现结果,这是值得怀疑的。尽管它能够很好地与SQL接口,但除此之外,它还是一种相当静态的语言。

另一方面,这对pl / perl来说没问题。