有没有办法绕过静态IN子句中1000项的Oracle 10g限制?我有一个以逗号分隔的列表,其中列出了我想在IN子句中使用的许多ID,有时这个列表可能超过1000个项目,此时Oracle会抛出错误.查询与此类似...
select * from table1 where ID in (1,2,3,4,...,1001,1002,...)
Otávio Décio.. 89
将值放在临时表中,然后执行select in where in(从temptable中选择id)
将值放在临时表中,然后执行select in where in(从temptable中选择id)
我几乎可以肯定你可以使用OR在多个IN之间拆分值:
select * from table1 where ID in (1,2,3,4,...,1000) or ID in (1001,1002,...,2000)
您可以尝试使用以下表单:
select * from table1 where ID in (1,2,3,4,...,1000) union all select * from table1 where ID in (1001,1002,...)
select column_X, ... from my_table where ('magic', column_X ) in ( ('magic', 1), ('magic', 2), ('magic', 3), ('magic', 4), ... ('magic', 99999) ) ...
你从哪里获得id的列表?由于它们是数据库中的ID,它们是否来自之前的一些查询?
当我在过去看到这个时,原因是: -
缺少参考表,正确的方法是添加新表,在该表上放置一个属性并加入它
从数据库中提取id列表,然后在后续SQL语句中使用(可能在以后或在其他服务器或其他任何服务器上).在这种情况下,答案是永远不要从数据库中提取它.存储在临时表中或只写一个查询.
我认为可能有更好的方法来重新编写这个代码,只是让这个SQL语句工作.如果您提供更多详细信息,您可能会得到一些想法
从表中使用......(...:
create or replace type numbertype as object (nr number(20,10) ) / create or replace type number_table as table of numbertype / create or replace procedure tableselect ( p_numbers in number_table , p_ref_result out sys_refcursor) is begin open p_ref_result for select * from employees , (select /*+ cardinality(tab 10) */ tab.nr from table(p_numbers) tab) tbnrs where id = tbnrs.nr; end; /
这是您需要提示的极少数情况之一,否则Oracle将不会在列ID上使用索引.这种方法的一个优点是Oracle不需要一次又一次地硬解析查询.使用临时表大多数时候都比较慢.
编辑1简化了程序(感谢jimmyorr)+示例
create or replace procedure tableselect ( p_numbers in number_table , p_ref_result out sys_refcursor) is begin open p_ref_result for select /*+ cardinality(tab 10) */ emp.* from employees emp , table(p_numbers) tab where tab.nr = id; end; /
例:
set serveroutput on create table employees ( id number(10),name varchar2(100)); insert into employees values (3,'Raymond'); insert into employees values (4,'Hans'); commit; declare l_number number_table := number_table(); l_sys_refcursor sys_refcursor; l_employee employees%rowtype; begin l_number.extend; l_number(1) := numbertype(3); l_number.extend; l_number(2) := numbertype(4); tableselect(l_number, l_sys_refcursor); loop fetch l_sys_refcursor into l_employee; exit when l_sys_refcursor%notfound; dbms_output.put_line(l_employee.name); end loop; close l_sys_refcursor; end; /
这将输出:
Raymond Hans