コレクション(配列)スクリプト

※コピーすると改行が抜ける場合はソースをダブルクリックして強調表示を外してからコピーしてください

SET SERVEROUTPUT ON

--VARRAY
DECLARE
  --配列数の宣言が必要
  TYPE TYPE_VARRAY IS VARRAY(4) OF VARCHAR2(1);
  V_VARRAY TYPE_VARRAY := TYPE_VARRAY();
BEGIN
--配列数3で初期化
  V_VARRAY := TYPE_VARRAY('A','B','C');
--VARRAY(4)で宣言しているのであと1拡張可能
  V_VARRAY.EXTEND(1);
  V_VARRAY(4) := 'D';
  DBMS_OUTPUT.PUT_LINE('配列数 ' || V_VARRAY.COUNT);
  FOR I IN 1..V_VARRAY.COUNT
  LOOP
    DBMS_OUTPUT.PUT_LINE(V_VARRAY(I));
  END LOOP;
END;
/

--ネストした表
DECLARE
  --配列数の宣言は不要
  TYPE TYPE_NESTED_TABLE IS TABLE OF VARCHAR2(10);
  V_NESTED_TABLE TYPE_NESTED_TABLE;
BEGIN
  --配列数3で初期化
  V_NESTED_TABLE := TYPE_NESTED_TABLE('A','B','C');
  --配列数は最大2147483647まで拡張可能
  V_NESTED_TABLE.EXTEND(1);
  V_NESTED_TABLE(4) := 'D';
  DBMS_OUTPUT.PUT_LINE('配列数 ' || V_NESTED_TABLE.COUNT);
  FOR I IN V_NESTED_TABLE.FIRST..V_NESTED_TABLE.LAST
  LOOP
    DBMS_OUTPUT.PUT_LINE(V_NESTED_TABLE(I));
  END LOOP;
END;
/

--結合配列
DECLARE
  --数字型配列(添え字数字)
  TYPE TYPE_ASSOC_ARRAY1 IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  --文字型配列(添え字数字)
  TYPE TYPE_ASSOC_ARRAY2 IS TABLE OF VARCHAR2(10) INDEX BY PLS_INTEGER;
  --文字型配列(添え字文字)
  TYPE TYPE_ASSOC_ARRAY3 IS TABLE OF VARCHAR2(10) INDEX BY VARCHAR2(10);
  V_ASSOC_ARRAY1 TYPE_ASSOC_ARRAY1;
  V_ASSOC_ARRAY2 TYPE_ASSOC_ARRAY2;
  V_ASSOC_ARRAY3 TYPE_ASSOC_ARRAY3;
  
  I VARCHAR2(10);
BEGIN
  --初期化不要、添え字が連続している必要がない
  V_ASSOC_ARRAY1(3) := 111;
  V_ASSOC_ARRAY1(5) := 222;
  V_ASSOC_ARRAY2(3) := 'abc';
  V_ASSOC_ARRAY2(6) := 'ghi';
  V_ASSOC_ARRAY3('soeji1') := 'def';
  V_ASSOC_ARRAY3('soeji2') := 'jkl';

  --配列数取得
  DBMS_OUTPUT.PUT_LINE('V_ASSOC_ARRAY1の配列数 ' || V_ASSOC_ARRAY1.COUNT);
  DBMS_OUTPUT.PUT_LINE('V_ASSOC_ARRAY2の配列数 ' || V_ASSOC_ARRAY2.COUNT);
  DBMS_OUTPUT.PUT_LINE('V_ASSOC_ARRAY3の配列数 ' || V_ASSOC_ARRAY3.COUNT);

  --全要素の取得
  I := V_ASSOC_ARRAY3.FIRST;
  LOOP
    EXIT WHEN(I IS NULL);
    DBMS_OUTPUT.PUT_LINE('V_ASSOC_ARRAY3(' || I ||') =' || V_ASSOC_ARRAY3(I));
    I := V_ASSOC_ARRAY3.NEXT(I);
  END LOOP;
END;
/

--ネストしたテーブルのマルチレベルコレクション(多次元配列)
DECLARE
  --配列数の宣言は不要
  TYPE TYPE_NESTED_TABLE IS TABLE OF VARCHAR2(10);
  TYPE TYPE_NESTED_NESTED_TABLE IS TABLE OF TYPE_NESTED_TABLE;
  V_NESTED_NESTED_TABLE TYPE_NESTED_NESTED_TABLE;
BEGIN
  --3*2の配列
  V_NESTED_NESTED_TABLE := TYPE_NESTED_NESTED_TABLE(TYPE_NESTED_TABLE('A','B'),TYPE_NESTED_TABLE('C','D'),TYPE_NESTED_TABLE('E','F'));
  DBMS_OUTPUT.PUT_LINE('配列数 ' || V_NESTED_NESTED_TABLE.COUNT);
  DBMS_OUTPUT.PUT_LINE('V_NESTED_NESTED_TABLE(1)(2)=' || V_NESTED_NESTED_TABLE(1)(1));
  DBMS_OUTPUT.PUT_LINE('V_NESTED_NESTED_TABLE(1)(2)=' || V_NESTED_NESTED_TABLE(1)(2));
  DBMS_OUTPUT.PUT_LINE('V_NESTED_NESTED_TABLE(2)(1)=' || V_NESTED_NESTED_TABLE(2)(1));
  DBMS_OUTPUT.PUT_LINE('V_NESTED_NESTED_TABLE(2)(2)=' || V_NESTED_NESTED_TABLE(2)(2));
  DBMS_OUTPUT.PUT_LINE('V_NESTED_NESTED_TABLE(3)(1)=' || V_NESTED_NESTED_TABLE(3)(1));
  DBMS_OUTPUT.PUT_LINE('V_NESTED_NESTED_TABLE(3)(2)=' || V_NESTED_NESTED_TABLE(3)(2));
END;
/


--コレクション・メソッド
COUNT・・・要素数取得
DELETE(n)・・・n番目の要素を削除、引数なしは全要素を削除、(n,m)はn~mの範囲を削除
EXISTS(n)・・・n番目の要素が存在するか判定、例外の発生なくNULLチェックが可能
EXTEND(n)・・・コレクションをn個拡張する。引数がない場合は(1)と同等、(n,i)と指定するとi番目の要素をn個拡張
FIRST・・・先頭要素取得
LAST・・・・後尾要素取得
LIMIT・・・最大サイズのチェック
NEXT(n)・・・n番目の次の要素のインデックス取得(無ければ戻り値NULL)
PRIOR(n)・・n番目の次の要素の前のインデックス取得(無ければ戻り値NULL)
TRIM(n)・・・コレクションの末尾からn個縮小、引数がない場合は(1)と同等

--集合演算子(コレクション同士の比較)
コレクション1 IN (コレクション2,コレクション3・・・)・・・SQLのIN句のコレクションのどれかに一致するか
コレクション1 SUBMULTISET OF コレクション2・・・コレクション1がコレクション2のサブセットであるか
CARDINALITY(コレクション1)・・・・・値の数
CARDINALITY(SET(コレクション1)・・・一意な値の数
x MEMBER OF コレクション1・・・xの値を持つ要素があるか
コレクション1 IS A SET・・・重複した値を持つか
コレクション1 IS EMPTY・・・空のコレクションか



マニュアル

Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス(10.2)
PL/SQL ユーザーズ・ガイドおよびリファレンス(10.2)
★ORACLE案件承ります