使用 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_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,只是编译没问题所以无法确定任何问题。
警告:像这样的动态 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_ID
和 i.CUSTOMER_ID
来检查它们的值。
动态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_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,只是编译没问题所以无法确定任何问题。
警告:像这样的动态 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_ID
和 i.CUSTOMER_ID
来检查它们的值。