动态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的连接中一定有问题,因为编译没问题,所以无法查明任何内容。
答案 0 :(得分:2)
警告:像这样的动态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;
这仍然需要在l_prefix
进行SQL注入,但如果以编程方式控制该值,则可能没问题。另外,将SQL的构造和SQL的执行分为两个步骤,可以更轻松地将EXECUTE IMMEDIATE
替换为DBMS_OUTPUT.PUT_LINE(SQL);
,以检查查询是否存在语法错误。您还可以DBMS_OUTPUT.PUT_LINE
参数i.CUSTOMER_REF_ID
和i.CUSTOMER_ID
来检查其值。