在PL / PGSQL动态SQL内部函数中引用局部变量

时间:2015-06-10 15:33:28

标签: sql postgresql function plpgsql dynamic-sql

我有一个用于数据处理的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的值,但我只知道列名。

当我尝试运行该功能时,我收到错误:

  

错误:缺少FROM-clause条目表" x"其中:PL / pgSQL   在EXECUTE语句中使用myfunc()第23行

1 个答案:

答案 0 :(得分:2)

这个有趣的问题:

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 Commands9.4.1. format