动态引用函数中的列名

时间:2014-02-15 22:26:11

标签: postgresql

下面是一个精简的例子,展示了我的问题的关键。

我有一个调用子函数(sub_test_function)的函数(test_column_param),并从正在循环的列查询中传入一个值。问题是我不知道要在运行时传递到sub_test_function的列的名称。列的名称传递给test_column_param,我想使用该值从记录集中动态提取正确的列值。但我没有运气。

我发现有很多帖子有各种各样的工作,但似乎都没有解决手头的问题。在实际代码中,我正在处理从sql_qry返回的100个列,并且具有需要动态传递到子函数调用的多个列参数。非常感谢任何建议。

CREATE TABLE demo.a_test
(
 col_a integer,
 col_b integer,
col_c integer
);

_

INSERT INTO demo.a_test(col_a, col_b, col_c) VALUES (5, 10, 15);
INSERT INTO demo.a_test(col_a, col_b, col_c) VALUES (20, 25, 30);
INSERT INTO demo.a_test(col_a, col_b, col_c) VALUES (35, 40, 45);

-

CREATE OR REPLACE FUNCTION demo.sub_test_function(col_value integer)
RETURNS integer as $$
begin
return col_value;
end; $$
LANGUAGE plpgsql;

_

CREATE OR REPLACE FUNCTION demo.test_column_param(col_name text)
RETURNS void as $$
declare
sql_qry text;
sql_data record;
sql_func_call text;
sub_func_ret integer;

begin
sql_qry:= 'select * from demo.a_test;';

 --this outputs 10,25,40 as expected
 for sql_data in execute sql_qry loop
sql_func_call:= 'select * from demo.sub_test_function (' || sql_data.col_b || ');';
execute sql_func_call into sub_func_ret;

raise notice '%', sub_func_ret;

 end loop;
end; $$
 LANGUAGE plpgsql;

_

select * from demo.test_column_param('col_b');

以下尝试将参数值与记录引用结合使用会失败并显示相关的错误消息

--ERROR: record "sql_data" has no field "col_name" 
 for sql_data in execute sql_qry loop
sql_func_call:= 'select * from demo.sub_test_function (' || sql_data.col_name || ');';
execute sql_func_call into sub_func_ret;

raise notice '%', sub_func_ret;

 end loop;

_

--ERROR: syntax error at or near "." 
for sql_data in execute sql_qry loop
sql_func_call:= 'select * from demo.sub_test_function (' || sql_data || '.' || col_name || ');';
execute sql_func_call into sub_func_ret;

raise notice '%', sub_func_ret;

end loop;

_

--ERROR: schema "sql_data" does not exist
for sql_data in execute sql_qry loop
sql_func_call:= 'select * from demo.sub_test_function (' || sql_data.quote_ident(col_name) || ');';
execute sql_func_call into sub_func_ret;

raise notice '%', sub_func_ret;

end loop;

1 个答案:

答案 0 :(得分:0)

使用列名

动态创建初始查询
CREATE OR REPLACE FUNCTION demo.test_column_param(col_name text)
RETURNS void as $$
declare
sql_qry text;
sql_data record;

begin
  sql_qry:= 'select demo.sub_test_function(' || col_name || )' as value from demo.a_test;';

  for sql_data in execute sql_qry loop

    raise notice '%', sql_data.value;

  end loop;
end; $$
 LANGUAGE plpgsql;