2016-11-03 9 views
1

Попытка выполнить следующее:Выполнение топка с форматом() вызывает ошибку

DO $$ 
BEGIN 
EXECUTE format('INSERT INTO public."EWcfgvars" (idinstrum, varname, enable, subaddr, id_device, id_synchronization_request, pupdate) VALUES (4, %s, 1, 0, 122, 1, 1464022764);', 'test'); 
    END 
$$; 

Я получаю эту ошибку:

[42703] ERROR: column "test" does not exist 
Where: PL/pgSQL function inline_code_block line 3 at EXECUTE statement 

Что случилось с моим DDL?

+0

Почему вы используете динамический SQL для этого? Это не нужно для этого примера. –

ответ

2

Заполнитель %s поместит значение из параметра «как есть» в строку. Но вы хотите, чтобы параметр обрабатывался как литерал (константа).

Вы должны использовать заполнитель %L для этого:

format('.... (4, %L, 1, 0, 122, 1, 1464022764)', 'test')

Для execute вы также не должны прекращать заявление с ;

+0

Вам не нужна точка с запятой в * end * командной строки, переданная в 'EXECUTE'. Однако это необходимо для нескольких операторов. Точно так же, как в теле SQL-функций: точка с запятой после команды * last * является шумом. Кроме того, предпочтительно, чтобы * значения * были переданы с предложением 'USING'. Конкатенация их как строковых литералов дороже и подвержена ошибкам. –

0

What's wrong with my DDL?

Функция format выводит строку в соответствии с некоторой строкой формата стиля printf. Ваша строка

format('INSERT INTO public."EWcfgvars" (...) VALUES (4, %s, 1, 0, 122, 1, 1464022764);', 'test') 

становится

INSERT INTO public."EWcfgvars" (...) VALUES (4, test, 1, 0, 122, 1, 1464022764); 

который является вставка оператор пытается вставить значение столбца test для второго значения.


Для вставки test в виде строки, вы можете попробовать Dollar-quoted String Constants, например,

format('INSERT INTO public."EWcfgvars" (...) VALUES (4, %s, 1, 0, 122, 1, 1464022764);', $$'test'$$) 
+2

Использование '% L', чтобы Postgres обрабатывал правильный литерал, намного лучше –

1

@Olaf и @a_horse объяснили вашу проблему. Решение:

Либо

EXECUTE format($$ 
    INSERT INTO public."EWcfgvars" (idinstrum, varname, enable, subaddr, id_device, id_synchronization_request, pupdate) VALUES 
    (4, %L, 1, 0, 122, 1, 1464022764); 
    $$', 'test' 
); 

Или execute без format

EXECUTE $$ 
    INSERT INTO public."EWcfgvars" (idinstrum, varname, enable, subaddr, id_device, id_synchronization_request, pupdate) 
    VALUES (4, $1, 1, 0, 122, 1, 1464022764); 
    $$ using 'test'; 
+0

' USING' для * значений * - это путь. –