使用 EXECUTE IMMEDIATE 的动态 SQL 语法

Dynamic SQL syntax using 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是table名字前缀的参数,赋值是T_ i.CUSTOMER_REF_IDi.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,只是编译没问题所以无法确定任何问题。

警告:像这样的动态 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 的构造和 SQL 的执行分成两个步骤,可以让您更轻松地将 EXECUTE IMMEDIATE 替换为 DBMS_OUTPUT.PUT_LINE(SQL); 以检查查询是否存在语法错误。您还可以 DBMS_OUTPUT.PUT_LINE 您的参数 i.CUSTOMER_REF_IDi.CUSTOMER_ID 来检查它们的值。