Reputation: 1499
I have really interesting problem.
I have user-defined table type
create or replace TYPE "TABLE_OF_NUMBER" AS TABLE OF NUMBER
I have table with millions of rows - calls
I have pl/sql block which works okay
declare
v_calls TABLE_OF_NUMBER;
begin
select id bulk collect
into v_calls
from calls;
end;
I have another pl/sql block which gives me an error
declare
v_calls TABLE_OF_NUMBER;
t1 number;
begin
select id bulk collect
into v_calls
from calls;
select count(*) into t1 from table(v_calls);
end;
ORA-22813: Operand value exceeds system limits.
And I found an explanation of error:
Cause: Object or Collection value was too large. The size of the value might have exceeded 30k in a SORT context, or the size might be too big for available memory.
My actual goal is to get this:
declare
v_calls TABLE_OF_NUMBER;
v_events TABLE_OF_NUMBER;
begin
select id bulk collect
into v_calls
from calls;
select id bulk collect
into v_events
from events
where call_id in (select * from table(v_calls));
end;
But I already find out that problem command is select * from table(v_calls)
I didn't find anything about restrictions for TABLE(user_defind_table)
command.
Does anyone know what is the problem and how can I avoid it?
Upvotes: 3
Views: 1856
Reputation: 1499
The restriction for select * from table(v_calls)
could be found here
I find few solutions:
As @Stawros said - use bulk collect ... limit
In my case performance degrades dramatically, so it isn't solution for me
Use temporary tables instead of user defined tables. It helps avoid error, but performance still really poor
Change whole code (logic) - unfortunately, that is my way.
Upvotes: 1
Reputation: 935
Possible solution:
declare
v_calls TABLE_OF_NUMBER;
v_events TABLE_OF_NUMBER;
v_events_tmp TABLE_OF_NUMBER;
cursor cur_calls is
select id
from calls;
begin
open cur_calls;
loop
fetch cur_calls
bulk collect
into v_calls
limit 1000;
exit when v_calls.count = 0;
select id bulk collect
into v_events_tmp
from events
where call_id in (select * from table(v_calls));
v_events := v_events_tmp MULTISET UNION v_events;
end loop;
close cur_calls;
end;
Upvotes: 3