如何在PostgreSQL中使用动态列名

时间:2019-02-26 07:35:13

标签: postgresql plpgsql dynamic-sql

我想在查询中使用动态列名,所以我使用execute format。但是我的查询不起作用。这是我的查询...

create or replace function container_type() returns table (contType text) as 
$func$ 
declare 
    containerType text[] := '{d20, r20, h20, rh20, e20, d40, r40, h40, rhc, e40, 45, tank, tk40, tk45, e45, r45, rh45, h45}';
    column01 text;
    column02 text;
begin
    FOR i IN 1 .. array_upper(containerType, 1)
    loop
    column01 = upper(containerType[i]);
    column02 = concat('"booking_', containerType[i], '"');

    execute
    format(
        'insert into tmp_booking_containers (
            booking_data_source,
            booking_place_of_creation,
            booking_prefix,
            booking_number,
            booking_prefix_number,
            booking_container_type,
            booking_container_quantity
        ) select 
            booking_data_source,
            booking_place_of_creation,
            booking_prefix,
            booking_number,
            booking_prefix_number,
            $1,
            $2
        from dim_booking_masters 
        where $2 != 0'
    ) using column01, column02;

    end loop;
end
$func$ LANGUAGE plpgsql STABLE;

这是我运行函数时显示的错误:

enter image description here

1 个答案:

答案 0 :(得分:1)

您正在混淆formatUSING的{​​{1}}子句。

EXECUTE将其第一个参数中出现的format%I%L(危险!不可逃避!)替换为以下参数(广播到{{1} }。

如果需要插入表名和列名之类的内容,可以使用它。

%s的{​​{1}}子句用于指定参数的自变量,就像在准备好的语句中一样。参数绑定到textUSING(等等)占位符。您只能在SQL中也可以使用某种类型的常量的地方使用参数。

这两种技术都可以防止SQL注入。

您的代码应如下所示:

EXECUTE