【问题标题】:Dynamic SQL syntax using EXECUTE IMMEDIATE使用 EXECUTE IMMEDIATE 的动态 SQL 语法
【发布时间】:2018-09-27 16:33:04
【问题描述】:

动态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_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的串联一定有问题,只是无法确定任何问题,因为编译很好。

【问题讨论】:

  • dbms_output.put_line替换成execute immediate,用括号看看输出查询,和静态更新语句匹配吗?

标签: oracle dynamic-sql ora-00904 execute-immediate


【解决方案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;

这仍然会受到l_prefix 的 SQL 注入影响,但如果您以编程方式控制该值,则可能没问题。此外,将 SQL 的构建和 SQL 的执行分为两个步骤,使您可以更轻松地将 EXECUTE IMMEDIATE 替换为 DBMS_OUTPUT.PUT_LINE(SQL); 以检查查询是否存在语法错误。你也可以想DBMS_OUTPUT.PUT_LINE你的参数i.CUSTOMER_REF_IDi.CUSTOMER_ID来检查它们的值。

【讨论】:

  • 如果我有多个EXECUTE IMMEDIATE 分配给L_SQL 为什么只执行第一条语句?我应该分配给不同的变量吗?
  • 我明白了..它需要不同的绑定变量来引用每个 EXECUTE IMMEDIATE 语句
猜你喜欢
  • 2021-04-15
  • 1970-01-01
  • 2021-04-15
  • 2014-07-11
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多