【问题标题】:Concat CLOB in PL/SQL for execute immediatePL/SQL 中的 Concat CLOB 用于立即执行
【发布时间】:2010-12-09 21:36:53
【问题描述】:

我需要将函数签名更改为具有 CLOB 类型的参数 (p_param),之前的类型是 nvarchar2。当现有代码使用 || 时,这给我带来了麻烦连接。

这是现有的 sn-p,它对 NVarchar2 工作得很好,但显然当你使用 || 时连接 CLOB 时会将其视为 nvarchar2,当超出 nvarchar2 的字符限制时,这是一个问题。

 execute immediate    
    'select p.person_id 
     from person p where p.id in (' || p_param || ')'
 bulk collect into persons;

我试着把上面的sn-p改成

  execute immediate   
   concat(concat('select p.id from person p where p.person_id in(',p_param),')')
  bulk collect into members;

这不能编译,我得到一个错误,

PLS-00382:表达式类型错误

我是 PL/SQL 新手,感谢您的帮助。

【问题讨论】:

  • 您是否正在构建一个人员列表,以至于它不适合 VARCHAR2 或 NVARCHAR2 变量?我不认为 Oracle 喜欢有那么长的 SQL。我会完全质疑这种方法。
  • 是的,我完全同意你的看法。我正在维护一些代码,并希望避免重写整个代码。

标签: sql database oracle plsql


【解决方案1】:

只要您必须修改这个特定的 sn-p 代码以使用 DBMS_SQL,我强烈考虑更改它以完全消除动态 SQL 方法。相反,我会采用 Tom 的 str2tbl 函数,将其修改为采用 CLOB(后续回复有 already done this),然后将代码更改为

select p.person_id 
  bulk collect into persons
  from person p 
 where p.id in (select column_value
                  from str2tbl( p_param ))

至少,这将使您避免创建大量不可共享的语句,减少硬解析的次数和解析所花费的时间,并减少共享池的压力。它还可以降低 SQL 注入攻击等风险。

【讨论】:

    【解决方案2】:

    在 11g 之前,您不能将 CLOB 用于 EXECUTE IMMEDIATE。在此之前,您需要切换到 DBMS_SQL。

    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:7032414607769#2445120800346017454

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-14
      • 2023-03-31
      • 2015-03-04
      • 2018-02-25
      相关资源
      最近更新 更多