Как использовать динамическое имя столбца в PostgreSQL - PullRequest
0 голосов
/ 26 февраля 2019

Я хочу использовать динамические имена столбцов в своем запросе, поэтому я использую 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 голосов
/ 26 февраля 2019

Вы смешиваете format и предложение USING в EXECUTE.

format заменяет вхождения %I, %L и %s (опасность! Не избежать!) в первом аргументе со следующими аргументами (приведен к text).

Вы используете его, если вам нужно интерполировать такие вещи, как имена таблиц и столбцов.

Предложение USINGEXECUTE - указать аргументы для параметров, как в подготовленных инструкциях.Аргументы связаны с заполнителями $1, $2 (и т. Д.).Вы можете использовать только те параметры, в которых вы также можете использовать константу некоторого типа в SQL.

Оба метода защищают вас от внедрения SQL.

Ваш код должен выглядеть следующим образом:

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,
                %I,
                %I
            from dim_booking_masters 
            where %I != 0',
            column01, column2, column02;
...