在 PL/PGSQL 动态 SQL 内部函数中引用局部变量
Posted
技术标签:
【中文标题】在 PL/PGSQL 动态 SQL 内部函数中引用局部变量【英文标题】:Reference Local Variable In PL/PGSQL Dynamic SQL Inside Function 【发布时间】:2015-06-10 15:33:28 【问题描述】:我有一个用于数据处理的 PL/PGSQL 函数。我需要先从表中选择每一行,然后检索每列的列名和相关值。所以基本上我将记录取消旋转到水平状态。这是必要的,因为它们将进入键/值存储而不是水平存储。
这是我目前所拥有的函数的摘要:
CREATE OR REPLACE FUNCTION myfunc()
RETURNS INT AS
$BODY$
DECLARE
x record;
aesql varchar;
aeval varchar;
y information_schema.columns%rowtype;
BEGIN
FOR x IN
SELECT * FROM mytable
LOOP
FOR y in
SELECT * FROM information_schema.columns where table_schema = 'public' AND table_name = 'mytable'
loop
execute 'select cast(x.'||y.column_name||' as varchar) into aeval';
end loop;
-- add processing for aeval once the dynamic sql is figured out
END LOOP;
RETURN 1;
END;
$BODY$ LANGUAGE plpgsql VOLATILE;
我已经解决了这么多问题,以至于我的理解是,要执行一条执行语句,它应该是一个 CRUD 查询或类似的东西。我尝试直接分配的任何查询,例如
execute 'aeval := x.'||y.column_name;
如果我使用 ':aeval' 等,'aeval' 或 ':' 的语法错误失败。
那么有谁知道这是否可行,以及我可以如何执行这个动态 sql?总结一下,我需要获取记录 x 的值,但我只知道列名。
当我尝试运行该函数时,我收到错误:
错误:表“x”缺少 FROM 子句条目其中:PL/pgSQL 在 EXECUTE 语句中执行 myfunc() 第 23 行
【问题讨论】:
【参考方案1】:这个有趣的查询:
select
translate(string_to_array(mytable.*::text,',')::text,'()','')::text[]
from mytable;
将 mytable 中的行作为文本数组返回。在函数中循环数组会容易得多:
create or replace function myfunc()
returns setof text language plpgsql
as $$
declare
eaval text;
x text[];
begin
for x in
select translate(string_to_array(mytable.*::text,',')::text,'()','')::text[]
from mytable
loop
foreach eaval in array x loop
return next eaval;
end loop;
return next '-- next row --';
end loop;
end $$;
select * from myfunc();
带参数的函数 - 表名:
create or replace function myfunc(table_name text)
returns setof text language plpgsql
as $$
declare
eaval text;
x text[];
begin
for x in
execute format($fmt$
select translate(string_to_array(%s.*::text,',')::text,'()','')::text[]
from %s
$fmt$,
table_name, table_name)
loop
foreach eaval in array x loop
return next eaval;
end loop;
return next '-- next row --';
end loop;
end $$;
select * from myfunc('mytable');
select * from myfunc('myschema.myanothertable');
阅读更多:39.5.4. Executing Dynamic Commands 和 9.4.1. format
【讨论】:
这很酷。如果您知道如何通过将表格指定为字符串或对象来执行此操作,那么奖励积分?例如,如果我想在几种不同类型的表上运行它怎么办?以上是关于在 PL/PGSQL 动态 SQL 内部函数中引用局部变量的主要内容,如果未能解决你的问题,请参考以下文章