您可能会考虑一些选项,但它们可能需要更改,无论是如何执行SQL语句或SQL语句本身。
使用DBMS_SQL代替EXECUTE IMMEDIATE - DBMS_SQL(见http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sql.htm)是难度比EXECUTE IMMEDIATE使用,但可以提供对过程的更多控制 - 通过名称绑定,包括能力(通过DBMS_SQL.BIND_VARIABLE和DBMS_SQL.BIND_ARRAY)而不是按位置。
使用EXECUTE IMMEDIATE与WITH条款 - 你也许能够重组查询中使用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。这可能会影响查询的性能,但这可能是一个可接受的折中方案。
不要使用动态SQL - 当然,如果您不需要动态SQL,则不需要使用EXECUTE IMMEDIATE,因此“仅限位置”限制不适用。你确定你确实需要使用动态SQL吗?
编辑:如果您使用动态SQL,因为你有一个可变数量的OR条件就像你在你的编辑发布的,你也许可以通过执行下列操作之一,以避免使用动态SQL:
如果OR条件来自表(或查询) - 加入到该表(或查询),而不是使用OR条件列表。例如,如果CAT,帽子和MAT是在一个名为在名为YOUR_CRITERIA_TABLE表YOUR_CRITERIA列中列出你可能会在WHERE子句中的东西,如OBJECT_NAME LIKE '%' || YOUR_CRITERIA_TABLE.YOUR_CRITERIA || '%'.
添加YOUR_CRITERIA_TABLE到FROM条款并更换OBJECT_NAME LIKE '%CAT% OR OBJECT_NAME LIKE '%MAT% OR OBJECT_NAME LIKE '%HAT% OR OBJECT_NAME LIKE '%MAT%,否则可能会将条件放在全局临时表中 - 如果您的条件不是来自表(或查询),您可以(在设计时,不在运行时)创建一个全局临时表来保存它们,并且然后在运行时将标准插入到全局临时表中,然后按第1项所述加入。
或者,您可以将标准置于嵌套的t能够 - 这与第2项相似,只是使用嵌套表(使用CREATE TYPE...IS TABLE OF创建的表)而不是全局临时表。您可以创建或拥有嵌套表格类型,或者使用内置类型,如SYS.ODCIVARCHAR2LIST。在PL/SQL,你会填充此类型的变量,然后在第1项
使用它像一个“真正的”表像第3项的一个例子可能看起来像:
DECLARE
tblCriteria SYS.ODCIVARCHAR2LIST;
BEGIN
tblCriteria := SYS.ODCIVARCHAR2LIST();
-- In "real" code you might populate the nested table in a loop.
-- This example populates it explicitly so that it will compile. For the
-- purpose of the example, we could have populated the nested table in
-- a single statement:
-- tblCriteria := SYS.ODCIVARCHAR2LIST('CAT', 'HAT', 'MAT');
tblCriteria.EXTEND(1);
tblCriteria(tblCriteria.LAST) := 'CAT';
tblCriteria.EXTEND(1);
tblCriteria(tblCriteria.LAST) := 'HAT';
tblCriteria.EXTEND(1);
tblCriteria(tblCriteria.LAST) := 'MAT';
FOR rec IN
(
SELECT
USER_OBJECTS.*
FROM
USER_OBJECTS,
TABLE(tblCriteria) YOUR_NESTED_TABLE
WHERE
USER_OBJECTS.OBJECT_NAME LIKE '%' || YOUR_NESTED_TABLE.COLUMN_VALUE || '%'
)
LOOP
-- Do something. For example, print out the object name.
DBMS_OUTPUT.PUT_LINE(rec.OBJECT_NAME);
END LOOP;
END;