Postgres - 从记录变量动态引用列

时间:2015-12-22 07:58:31

标签: postgresql variables record

我无法动态引用记录变量类型列。我在网上发现了大量的技巧,但主要是关于触发器,我真的希望答案不是“它无法完成”......我有一个非常具体和简单的需求,请参阅下面的示例代码;

首先,我有一个包含列名称列表的数组,名为“ lCols ”。我遍历一个记录变量来遍历我的数据,替换段中与我的列名完全匹配的值。

DECLARE lTotalRec RECORD;        
DECLARE lSQL text;
DECLARE lCols varchar[];

p_paragraph:= 'I am [names] and my surname is [surname]';

lSQL := 
    'select         
        p.names,
        p.surname
    from 
        person p
    ';

FOR lTotalRec IN
    execute lSQL        
LOOP
    -- Loop through the already created array of columns to replace the values in the paragraph
    FOREACH lVal IN ARRAY lCols
    LOOP
        p_paragraph := replace(p_paragraph,'[' || lVal || ']',lTotalRec.lVal); -- This is where my problem is, because lVal is not a column of lTotalRec directly like this      
    END LOOP;

    RETURN NEXT;
END LOOP;

我的返回值是针对“lTotalRec”中每条记录修改的段落

2 个答案:

答案 0 :(得分:1)

您可以使用record功能将json转换为row_to_json()值。使用此格式后,您可以使用->->>运算符按名称提取列。

在Postgres 9.4及更高版本中,您还可以使用效率更高的jsonb类型。

DECLARE lJsonRec jsonb;

...

FOR lTotalRec IN
    execute lSQL        
LOOP
    lJsonRec := row_to_json(lTotalRec)::jsonb;
    FOREACH lVal IN ARRAY lCols
    LOOP
        p_paragraph := replace(p_paragraph, '[' || lVal || ']', lJsonRec->>lVal);
    END LOOP;

    RETURN NEXT;
END LOOP;

有关详细信息,请参阅documentation

答案 1 :(得分:0)

您可以使用row_to_json()将行转换为JSON,然后使用json_object_keys()检索列名。

以下是一个例子:

drop table if exists TestTable;

create table TestTable (col1 text, col2 text);
insert into TestTable values ('a1', 'b1'), ('a2', 'b2');

do $$declare
    sql text;
    rec jsonb;
    col text;
    val text;
begin
sql := 'select row_to_json(row) from (select * from TestTable) row';
for rec in execute sql loop
    for col in select * from jsonb_object_keys(rec) loop
        val := rec->>col;
        raise notice 'col=% val=%', col, val;
    end loop;
end loop;
end$$;

打印:

NOTICE:  col=col1 val=a1
NOTICE:  col=col2 val=b1
NOTICE:  col=col1 val=a2
NOTICE:  col=col2 val=b2
DO