CREATE TYPE nums_list AS TABLE OF NUMBER;
What is maximum possible rows count in oracle's nested table ?
UPDATE
CREATE TYPE nums_list AS TABLE OF NUMBER;
CREATE OR REPLACE FUNCTION generate_series(from_n NUMBER, to_n NUMBER)
RETURN nums_list AS
ret_table nums_list := nums_list();
BEGIN
FOR i IN from_n..to_n LOOP
ret_table.EXTEND;
ret_table(i) := i;
END LOOP;
RETURN ret_table;
END;
SELECT count(*) FROM TABLE ( generate_series(1,4555555) );
This gives error: ORA-22813 operand value exceeds system limits, Object or Collection value was too large
The range of subscripts for a nested table is 1..2**31 so you can have 2**31 elements in the collection. That limit hasn't changed since at least 8.1.6 though, of course, it might change in the future.
Just as an additional observation, it isn't the nested table itself that is too large or using too much memory. With an exception handler you can see that the error is not being thrown by your function. You can populate the same thing in an anonymous block:
DECLARE
ret_table nums_list := nums_list();
BEGIN
FOR i IN 1..4555555 LOOP
ret_table.EXTEND;
ret_table(i) := i;
END LOOP;
dbms_output.put_line(ret_table.count);
END;
/
anonymous block completed
4555555
And you can call your function from a block too:
DECLARE
ret_table nums_list;
BEGIN
ret_table := generate_series(1,4555555);
dbms_output.put_line(ret_table.count);
END;
/
anonymous block completed
4555555
It's only when you use it as table collection expression that you get an error:
SQL Error: ORA-22813: operand value exceeds system limits
22813. 00000 - "operand value exceeds system limits"
*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.
*Action: Choose another value and retry the operation.
The cause text refers to the SORT context, and a sort is being done by your query:
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 29 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
| 2 | COLLECTION ITERATOR PICKLER FETCH| GENERATE_SERIES | 8168 | 16336 | 29 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------
As @a_horse_with_no_name suggested, you can avoid the problem by making your function pipelined:
CREATE OR REPLACE FUNCTION generate_series(from_n NUMBER, to_n NUMBER)
RETURN nums_list PIPELINED AS
BEGIN
FOR i IN from_n..to_n LOOP
PIPE ROW (i);
END LOOP;
RETURN;
END;
/
SELECT count(*) FROM TABLE ( generate_series(1,4555555) );
COUNT(*)
----------
4555555
That still does a SORT AGGREGATE
but it doesn't seem to mind any more. Not really sure why it does that in either case; perhaps someone else will be able to explain what it's doing. (I'm doing this in an 11gR2 instance by the way; I don't have a 12c instance to verify the behaviour is the same, but your symptoms suggest it will be). Or maybe it isn't the SORT context that's the issue, perhaps it is available memory. In my environment your version seems to consistently work up to 4177918 elements - which doesn't seem to be a significant number, so is likely to be environment related?
But it depends how you intend to use the collection; from a PL/SQL context your original version might be more suitable.
来源:https://stackoverflow.com/questions/24191257/what-is-maximum-rows-count-in-oracles-nested-table