在 PL/PGSQL 动态 SQL 内部函数中引用局部变量
Reference Local Variable In PL/PGSQL Dynamic SQL Inside Function
我有一个 PL/PGSQL 函数用于数据处理。我需要首先 select 来自 table 的每一行,然后检索列名和每列的关联值。所以基本上我将记录取消旋转到水平状态。这是必要的,因为它们将进入 key/value 存储而不是水平存储。
这是我目前拥有的函数的摘要:
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 的值,但我只知道列名。
当我尝试 运行 函数时,我收到错误消息:
ERROR: missing FROM-clause entry for table "x" Where: PL/pgSQL
function myfunc() line 23 at EXECUTE statement
这个有趣的查询:
select
translate(string_to_array(mytable.*::text,',')::text,'()','')::text[]
from mytable;
来自 mytable 的 returns 行作为文本数组。在函数中循环数组会容易得多:
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();
带参数的函数 - table 名称:
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');
我有一个 PL/PGSQL 函数用于数据处理。我需要首先 select 来自 table 的每一行,然后检索列名和每列的关联值。所以基本上我将记录取消旋转到水平状态。这是必要的,因为它们将进入 key/value 存储而不是水平存储。
这是我目前拥有的函数的摘要:
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 的值,但我只知道列名。
当我尝试 运行 函数时,我收到错误消息:
ERROR: missing FROM-clause entry for table "x" Where: PL/pgSQL function myfunc() line 23 at EXECUTE statement
这个有趣的查询:
select
translate(string_to_array(mytable.*::text,',')::text,'()','')::text[]
from mytable;
来自 mytable 的 returns 行作为文本数组。在函数中循环数组会容易得多:
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();
带参数的函数 - table 名称:
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');