使用绑定变量时如何解决错误“ORA:01-006:绑定变量不存在”?

Pan*_*tea 3 oracle query oracle-11g-r2 plsql error-handling

我有一个包含以下结构和数据的表:

create table TEST_TABLE
(
  item_number NUMBER,
  item_name   VARCHAR2(50),
  item_col    VARCHAR2(50),
  item_pol    VARCHAR2(50)
)
Run Code Online (Sandbox Code Playgroud)

样本数据:

item_number |  item_name|  item_col |  item_pol
------------------------------------------------
     1      |   blue    |     b     |   c
     2      |   red     |     d     |   a
     3      |   black   |     e     |   a
     4      |   yellow  |     d     |   b
Run Code Online (Sandbox Code Playgroud)

这是我尝试使用的示例过程bind variables

create or replace procedure test_bind_variable(res         out sys_refcursor,
                                               item_number varchar2,
                                               item_name   varchar2,
                                               item_col    varchar2,
                                               item_pol    varchar2) is

  qry varchar2(8000);

begin

  qry := 'select * from test_table where 1=1 ';

  if (item_number is not null) then
    qry := qry || ' and item_number = :1  ';
  end if;

  if (item_name is not null) then
    qry := qry || ' and item_name = :2 ';
  end if;

  if (item_col is not null) then
    qry := qry || ' and item_col= :3 ';
  end if;

  if (item_pol is not null) then
    qry := qry || ' and item_pol = :4 ';
  end if;

  dbms_output.put_line(qry);

  open res for  qry
    using item_number, item_name, item_col, item_pol;

end;
Run Code Online (Sandbox Code Playgroud)

问题是,当所有输入参数都有值时,该过程正常工作,没有任何错误,但是当只有一两个参数有值时,我收到此错误:ORA-01006: bind variable does not exist,。我怎么解决这个问题?有些参数可能有价值,有些则没有。

提前致谢

mus*_*cio 5

您可以完全避免动态 SQL(您也不应该将 PL/SQL 变量命名为与表列相同的名称):

create or replace procedure test_bind_variable(res         out sys_refcursor,
                                               p_item_number varchar2,
                                               p_item_name   varchar2,
                                               p_item_col    varchar2,
                                               p_item_pol    varchar2) is

  qry varchar2(8000);

begin

  open res for select * from test_table where
    (p_item_number is null or p_item_number = item_number) and
    (p_item_name is null or p_item_name = item_name) and
    (p_item_col is null or p_item_col = item_col) and
    (p_item_pol is null or p_item_pol = item_pol)

end;
Run Code Online (Sandbox Code Playgroud)

附言。确保您考虑了运算符优先级,与我不同。

  • 请注意,这会给优化器带来困难,因为它必须生成一个在所有情况下都合法的计划(全表扫描是唯一的可能性)。对于此类需求,建议使用动态 SQL。 (2认同)