Varray(可変サイズ配列)は、正の整数を値にマップするコレクション型です。ネストされたテーブルとは異なり、varray は常に密(dense)であり、要素が隣接して隙間なく格納されます。また、定義時に固定された最大サイズを指定する必要があります。
varray の利用シーン
以下の条件に該当する場合に varray を選択してください:
要素の最大数が事前に分かっている場合。
要素に順次アクセスする場合。
すべての要素を単一の単位として保存または取得する必要があります。
要素の最大数が不明である場合、またはコレクションが疎(sparse)になる可能性がある場合は、代わりにネストされたテーブルを使用してください。
仕組み
SPL の 3 種類のコレクション型は共通の動作を共有しますが、varray には次の 2 つの主要な制約があります:
固定された上限値:要素の最大数は型の定義時に設定され、その後は超過できません。
常に密であること:ネストされたテーブルとは異なり、varray は疎になることはありません。つまり、キーに対する値の割り当てに隙間が生じることはありません。
varray 変数を宣言すると、初期状態では null コレクションとなります。要素を参照または値を設定する前に、コンストラクターによる初期化が必要です。また、右辺が同一型の初期化済み varray である代入ステートメントを用いて、varray を初期化することもできます。
varray 型の定義
SPL プログラムの宣言セクションで、TYPE IS VARRAY 文を使用します:
TYPE varraytype IS { VARRAY | VARYING ARRAY }(maxsize)
OF { datatype | objtype };以下:
varraytype— varray 型に割り当てられる識別子。maxsize— 要素の最大数。この型の varray は、この数を超えることはできません。datatype—VARCHAR2やNUMBERなどのスカラー・データの型。objtype— 事前に定義済みのオブジェクトタイプ。
varray 型をデータベース内のすべての SPL プログラムから利用可能にするには、代わりに CREATE TYPE 文を使用してください。
varray 変数の宣言
型を定義した後、その型の変数を宣言します:
varray varraytypeここで:
varray— 変数に割り当てられる識別子。varraytype— 事前に定義済みの varray 型の識別子。
varray の初期化
varray を初期化するには、型のコンストラクターを呼び出します:
varraytype ([ { expr1 | NULL } [, { expr2 | NULL } ] [, ...] ])対象:
varraytype— コンストラクター名。これは varray 型の名前と同じです。コンストラクターは varray 内の要素数を決定し、この数は最大サイズ制限を超えてはなりません。expr1, expr2, ...— 要素の型と互換性のある式。要素を NULL に設定する場合は、NULLを指定します。引数リストが空の場合、要素を持たない空の varray が返されます。
varray 型がオブジェクトタイプから定義されている場合、各式はそのオブジェクトタイプのインスタンスを返す必要があります。このオブジェクトは、関数の戻り値、オブジェクトタイプのコンストラクターの戻り値、あるいは同一型の他の varray の要素のいずれかになります。
例:2 要素の varray の初期化
DECLARE
TYPE varray_typ IS VARRAY(2) OF CHAR(1);
v_varray varray_typ := varray_typ('A','B');初期化されていない varray に対して、EXISTSを除く任意のコレクション・メソッドを適用すると、COLLECTION_IS_NULL例外が発生します。
varray 要素のリファレンス
varray(n)[.element]以下:
varray— 事前に宣言済みの varray 変数の識別子。n— 正の整数インデックス。.element— varray 型がオブジェクトタイプから定義されている場合、そのオブジェクトタイプ内の属性を指定します。.elementを省略すると、オブジェクト全体を参照します。
varray の拡張
初期化後に、EXTEND メソッドを使用して、最大サイズ制限に達するまで varray に追加の要素を追加できます。
例外
| 例外 | 発生条件 |
|---|---|
SUBSCRIPT_BEYOND_COUNT | 現在のサイズを超えるが、最大サイズ制限内であるインデックスを参照した場合 |
SUBSCRIPT_OUTSIDE_LIMIT | 最大サイズ制限を超えるインデックスを参照した場合、または最大サイズ制限を超えて varray を拡張しようとした場合 |
COLLECTION_IS_NULL | 初期化されていない varray に対して、EXISTS を除く任意のコレクション・メソッドを適用した場合 |
例
以下の例では、最大 4 件の部署名を格納可能な varray を定義し、カーソルから値を読み込んで各部署名を出力します。
DECLARE
TYPE dname_varray_typ IS VARRAY(4) OF VARCHAR2(14);
dname_varray dname_varray_typ;
CURSOR dept_cur IS SELECT dname FROM dept ORDER BY dname;
i INTEGER := 0;
BEGIN
dname_varray := dname_varray_typ(NULL, NULL, NULL, NULL);
FOR r_dept IN dept_cur LOOP
i := i + 1;
dname_varray(i) := r_dept.dname;
END LOOP;
DBMS_OUTPUT.PUT_LINE('DNAME');
DBMS_OUTPUT.PUT_LINE('----------');
FOR j IN 1..i LOOP
DBMS_OUTPUT.PUT_LINE(dname_varray(j));
END LOOP;
END;出力結果:
DNAME
----------
ACCOUNTING
OPERATIONS
RESEARCH
SALES