3
CREATE TYPE nums_list AS TABLE OF NUMBER;

オラクルのネストされたテーブルで可能な最大行数は?

アップデート

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) );

これによりエラーが発生します:ORA-22813 operand value exceeds system limits, Object or Collection value was too large

4

2 に答える 2

3

追加の観察として、ネストされたテーブル自体が大きすぎたり、メモリを使いすぎたりしているわけではありません。例外ハンドラーを使用すると、関数によってエラーがスローされていないことがわかります。匿名ブロックに同じものを入力できます。

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

また、ブロックから関数を呼び出すこともできます。

DECLARE
  ret_table nums_list;
BEGIN
  ret_table := generate_series(1,4555555);
  dbms_output.put_line(ret_table.count);
END;
/

anonymous block completed
4555555

エラーが発生するのは、テーブル コレクション式として使用した場合のみです。

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.

原因テキストはSORT コンテキストを参照しており、クエリによって並べ替えが行われています。

------------------------------------------------------------------------------------------------------
| 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 |
------------------------------------------------------------------------------------------------------

@a_horse_with_no_name が示唆したように、関数をパイプライン化することで問題を回避できます。

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 

それでも問題はありSORT AGGREGATEませんが、もう気にしないようです。どちらの場合もなぜそうするのかよくわかりません。おそらく他の誰かがそれが何をしているのか説明できるでしょう。(ちなみに、11gR2 インスタンスでこれを行っています。動作が同じであることを確認するための 12c インスタンスはありませんが、症状はそうであることを示唆しています)。または、問題は SORT コンテキストではなく、使用可能なメモリである可能性があります。私の環境では、あなたのバージョンは最大 4177918 要素まで一貫して動作しているようです。これは重要な数ではないようで、環境に関連している可能性がありますか?

ただし、コレクションをどのように使用するかによって異なります。PL/SQL コンテキストからは、元のバージョンの方が適している可能性があります。

于 2014-06-13T16:34:19.537 に答える