Синтаксис динамического SQL с использованием EXECUTE IMMEDIATE
Оператор динамического обновления SQL, как показано ниже:
EXECUTE IMMEDIATE 'UPDATE '||l_prefix||'CRS_CUSTOMERS SET CUSTOMER_SOURCE_REF_ID = '||i.CUSTOMER_REF_ID||' WHERE CUSTOMER_ID = '||i.CUSTOMER_ID;
l_prefix
параметр содержит префикс имени таблицы, назначенное значение - T_i.CUSTOMER_REF_ID
а также i.CUSTOMER_ID
поля, извлеченные из курсора.
Ошибка динамического оператора ORA-00904: invalid identifier
когда данные получены.
Когда переписать его статическим способом, запрос работает нормально:
UPDATE T_CRS_CUSTOMERS SET CUSTOMER_SOURCE_REF_ID = i.CUSTOMER_REF_ID WHERE
CUSTOMER_ID = i.CUSTOMER_ID;
Я знаю, что это должно быть что-то не так в конкатенации динамического SQL, просто не могу точно определить это, так как компиляция в порядке.
1 ответ
ВНИМАНИЕ: Динамический SQL, подобный этому, подвержен атакам SQL-инъекций. По возможности переписывайте свой динамический SQL, чтобы вместо него использовать переменные связывания.
Вместо того, чтобы создавать свой динамический SQL следующим образом:
L_SQL := 'UPDATE '||l_prefix||'CRS_CUSTOMERS SET CUSTOMER_SOURCE_REF_ID = '||i.CUSTOMER_REF_ID||' WHERE CUSTOMER_ID = '||i.CUSTOMER_ID;
EXECUTE IMMEDIATE L_SQL;
Использовать этот:
L_SQL := 'UPDATE '||l_prefix||'CRS_CUSTOMERS SET CUSTOMER_SOURCE_REF_ID = :REF_ID WHERE CUSTOMER_ID = :CUST_ID';
EXECUTE IMMEDIATE L_SQL USING i.CUSTOMER_REF_ID, i.CUSTOMER_ID;
Это все еще подлежит внедрению SQL на l_prefix
, но если вы контролируете это значение программно, это может быть в порядке. Кроме того, разделение конструкции SQL и его выполнения на два этапа позволяет упростить замену EXECUTE IMMEDIATE
с DBMS_OUTPUT.PUT_LINE(SQL);
проверить ваш запрос на наличие синтаксических ошибок. Вы также можете хотеть DBMS_OUTPUT.PUT_LINE
ваши параметры i.CUSTOMER_REF_ID
а также i.CUSTOMER_ID
проверить их значения.