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

标签 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 的值,但我只知道列名。

当我尝试运行该函数时,我收到错误:

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 中的行作为文本数组返回。在函数中循环数组会更容易:

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

关于sql - 在 PL/PGSQL 动态 SQL 内部函数中引用局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30760903/

相关文章:

ruby-on-rails - 'fields' 和 'types' 是否允许用于 rails postgresql 表的名称?

sql - 查询 JSON 数组数据字段中的数据

c - 如何在C中将多个函数分组以折叠

sql - 在 PostgreSQL 中获取一个范围内的日期列表

javascript - JavaScript 中的内部函数会被提升吗?范围规则如何适用于它们?

c++ - 在 std::function 上强制执行 "noexcept"?

sql - SCOPE_IDENTITY 而不是插入触发器的解决方法

java - 是否可以从 Java 在 MySQL 中创建新帐户?

mysql - 如何编写 ORDER BY 子句以首先返回两个表中都有条目的结果?

sql - 无法解决临时表和 sys.objects 之间的排序规则冲突