在Oracle PL / SQL中重用绑定变量

时间:2012-07-26 00:12:38

标签: oracle plsql oracle10g

我对代码不断重复使用的联合会有一个沉重的SQL语句。我希望找出是否有办法重复使用单个绑定变量,而无需多次重复变量“USING”。

下面的代码返回“并非所有变量绑定”,直到我将“USING”行更改为“USING VAR1,VAR2,VAR1;”

我希望避免这种情况,因为我指的是:在两种情况下都是1 - 任何想法?

declare
var1 number :=1;
var2 number :=2;
begin
execute immediate '
select * from user_objects 
where 
rownum = :1
OR rownum = :2  
OR rownum = :1 '
using var1,var2;
end;
/

编辑:有关其他信息,我正在使用动态SQL,因为我还生成了一系列条件。

我对SQL数组不太好(我在我的代码中使用了游标,但我认为这会使问题过于复杂)但是伪代码是:

v_where varchar2(100) :='';
FOR i in ('CAT','HAT','MAT') LOOP
  v_where := v_where || ' OR OBJECT_NAME LIKE ''%' || i.string ||'%''
END;
  v_where := ltrim(v_where, ' OR');

然后将上面的SQL修改为:

execute immediate '
select * from user_objects 
where 
rownum = :1
OR rownum = :2  
OR rownum = :1 AND ('||V_WHERE||')'
using var1,var2;

2 个答案:

答案 0 :(得分:4)

不,不幸的是,EXECUTE IMMEDIATE的绑定变量必须按它们在语句中出现的顺序提供,并且绑定变量名称将被忽略。所以你必须在你的陈述中有:1,:2和:3。

答案 1 :(得分:4)

您可能会考虑一些选项,尽管它们可能需要更改,无论是执行SQL语句还是SQL语句本身。

  1. 使用DBMS_SQL代替EXECUTE IMMEDIATE - DBMS_SQL(请参阅http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sql.htm)比EXECUTE IMMEDIATE更难使用,但让您更好地控制流程 - 包括通过名称而不是按位置绑定的能力(通过DBMS_SQL.BIND_VARIABLEDBMS_SQL.BIND_ARRAY)。
  2. EXECUTE IMMEDIATEWITH子句一起使用 - 您可以重新构建查询以使用WITH子句在子查询中收集绑定变量开始,然后在需要时加入子查询(而不是直接引用绑定变量)。它可能看起来像with your_parameters as (select :1 as p1, :2 as p2 from dual) select * from your_table, your_parameters where your_table.some_column1 = your_parameters.p1 and your_table.some_column2 <= your_parameters.p1 and your_table.some_column3 = your_parameters.p2。这可能会影响查询的性能,但这可能是一种可接受的妥协。
  3. 不使用动态SQL - 当然,如果您不需要动态SQL,则不需要使用EXECUTE IMMEDIATE,因此“仅按位置绑定”限制会不适用。你确定你真的需要使用动态SQL吗?
  4. 编辑:如果您正在使用动态SQL,因为您在编辑中发布了可变数量的OR条件,则可以通过执行以下操作之一来避免使用动态SQL:

    1. 如果OR条件来自表格(或查询) - 加入该表格(或查询),而不是使用OR条件列表。例如,如果CAT,HAT和MAT列在名为YOUR_CRITERIA的表中名为YOUR_CRITERIA_TABLE的列中,则可以将YOUR_CRITERIA_TABLE添加到FROM子句中并替换{ OBJECT_NAME LIKE '%CAT% OR OBJECT_NAME LIKE '%MAT% OR OBJECT_NAME LIKE '%HAT% OR OBJECT_NAME LIKE '%MAT%子句中的{1}} WHERE
    2. 否则,您可以将条件放在全局临时表中 - 如果您的条件不是来自表(或查询),您可以(一次,在设计时,不在运行时)创建一个全局临时表来保存它们,然后在运行时将条件插入全局临时表,然后按照第1项中的描述加入它。
    3. 或者,您可以将条件放在嵌套表中 - 这类似于第2项,除了使用嵌套表(使用OBJECT_NAME LIKE '%' || YOUR_CRITERIA_TABLE.YOUR_CRITERIA || '%'.创建的表)而不是全局临时表。您可以创建或拥有嵌套表类型,也可以使用像CREATE TYPE...IS TABLE OF这样的内置表类型。在PL / SQL中,您将填充此类型的变量,然后像项目1中的“真实”表一样使用它。
    4. 第3项的示例可能如下所示:

      SYS.ODCIVARCHAR2LIST