有没有办法绕过静态IN子句中1000项的Oracle 10g限制?我有一个以逗号分隔的列表,其中列出了我想在IN子句中使用的许多ID,有时这个列表可能超过1000个项目,此时Oracle会抛出错误.查询与此类似...
select * from table1 where ID in (1,2,3,4,...,1001,1002,...)
Run Code Online (Sandbox Code Playgroud)
Otá*_*cio 89
将值放在临时表中,然后执行select in where in(从temptable中选择id)
小智 54
我几乎可以肯定你可以使用OR在多个IN之间拆分值:
select * from table1 where ID in (1,2,3,4,...,1000) or
ID in (1001,1002,...,2000)
Run Code Online (Sandbox Code Playgroud)
ric*_*ics 46
您可以尝试使用以下表单:
select * from table1 where ID in (1,2,3,4,...,1000)
union all
select * from table1 where ID in (1001,1002,...)
Run Code Online (Sandbox Code Playgroud)
Ser*_*11g 44
select column_X, ... from my_table
where ('magic', column_X ) in (
('magic', 1),
('magic', 2),
('magic', 3),
('magic', 4),
...
('magic', 99999)
) ...
Run Code Online (Sandbox Code Playgroud)
你从哪里获得id的列表?由于它们是数据库中的ID,它们是否来自之前的一些查询?
当我在过去看到这个时,原因是: -
我认为可能有更好的方法来重新编写这个代码,只是让这个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;
/
Run Code Online (Sandbox Code Playgroud)
这是您需要提示的极少数情况之一,否则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;
/
Run Code Online (Sandbox Code Playgroud)
例:
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;
/
Run Code Online (Sandbox Code Playgroud)
这将输出:
Raymond
Hans
Run Code Online (Sandbox Code Playgroud)