コレクション・メソッド

コレクション・メソッドはPL/SQLサブプログラムであり、コレクションに関する情報を戻すファンクションまたはコレクションに対する操作を実行するプロシージャのいずれかです。コレクション・メソッドを使用すると、コレクションの使用およびアプリケーションのメンテナンスが簡単になります。

表6-2に、コレクション・メソッドの概要を示します。

ノート:

NULLのコレクションで使用する場合に、事前定義の例外COLLECTION_IS_NULLが発生しないコレクション・メソッドはEXISTSのみです。

表6-2 コレクション・メソッド

メソッド 説明

DELETE

プロシージャ

コレクションから要素を削除します。

TRIM

プロシージャ

VARRAYまたはネストした表の末尾から要素を削除します。

EXTEND

プロシージャ

VARRAYまたはネストした表の末尾に要素を追加します。

EXISTS

ファンクション

VARRAYまたはネストした表の指定された要素が存在する場合のみTRUEを戻します。

FIRST

ファンクション

コレクションの最初の索引を戻します。

LAST

ファンクション

コレクションの最後の索引を戻します。

COUNT

ファンクション

コレクション内の要素の数を戻します。

LIMIT

ファンクション

コレクションに格納できる要素の最大数を戻します。

PRIOR

ファンクション

指定された索引の前の索引を戻します。

NEXT

ファンクション

指定された索引の後の索引を戻します。

コレクション・メソッドを起動する基本構文は、次のとおりです。

collection_name.method

構文の詳細は、「コレクション・メソッドの起動」を参照してください。

コレクション・メソッドの起動は、その型(ファンクションまたはプロシージャ)のPL/SQLサブプログラムの起動を指定できるすべての場所(SQL文を除く)で使用できます。(PL/SQLサブプログラムの概要は、「PL/SQLサブプログラム」を参照してください。)

サブプログラム内で、コレクション・パラメータは引数のプロパティがバインドされていることを前提にしています。コレクション・メソッドは、そのようなパラメータに適用できます。VARRAYパラメータの場合、パラメータ・モードに関係なく、LIMITの値は常にパラメータの型定義から導出されます。

ここでのトピック

DELETEコレクション・メソッド

DELETEは、コレクションから要素を削除するプロシージャです。

このメソッドには次の形式があります。

  • DELETEはすべての型のコレクションからすべての要素を削除します。

    この操作を実行すると、削除された要素に割り当てられていたメモリーは即座に解放されます。

  • 連想配列またはネストされた表(VARRAYではない)から削除する場合は次のとおりです。

    • DELETE(n)は、nの索引を持つ要素が存在する場合にその要素を削除します。それ以外の場合は何も実行しません。

    • DELETE(m,n)は、mnの両方が存在し、m <= nの場合に、mからnの範囲の索引を持つすべての要素を削除します。それ以外の場合は何も実行しません。

    これら2つのDELETE形式を使用する場合、PL/SQLは削除された要素のプレースホルダを保持します。したがって、削除された要素はコレクションの内部サイズに含まれるため、削除された要素に有効な値を代入してリストアすることができます。

例6-23 ネストした表でのDELETEメソッド

この例では、ネストした表の変数を宣言し、6つの要素を使用して初期化した後で、2番目の要素を削除してからリストアし、次に、要素の範囲を削除し、削除した要素の1つをリストアしてから、すべての要素を削除します。リストアされた要素は、それに対応する削除された要素と同じメモリー量を占有します。プロシージャprint_ntは、初期化の後および各DELETE操作の後に、ネストした表の変数を出力します。型nt_typeおよびプロシージャprint_ntは、例6-6で定義しています。

DECLARE
  nt nt_type := nt_type(11, 22, 33, 44, 55, 66);
BEGIN
  print_nt(nt);
 
  nt.DELETE(2);     -- Delete second element
  print_nt(nt);
 
  nt(2) := 2222;    -- Restore second element
  print_nt(nt);
 
  nt.DELETE(2, 4);  -- Delete range of elements
  print_nt(nt);
 
  nt(3) := 3333;    -- Restore third element
  print_nt(nt);
 
  nt.DELETE;        -- Delete all elements
  print_nt(nt);
END;
/

結果:

nt.(1) = 11
nt.(2) = 22
nt.(3) = 33
nt.(4) = 44
nt.(5) = 55
nt.(6) = 66
---
nt.(1) = 11
nt.(3) = 33
nt.(4) = 44
nt.(5) = 55
nt.(6) = 66
---
nt.(1) = 11
nt.(2) = 2222
nt.(3) = 33
nt.(4) = 44
nt.(5) = 55
nt.(6) = 66
---
nt.(1) = 11
nt.(5) = 55
nt.(6) = 66
---
nt.(1) = 11
nt.(3) = 3333
nt.(5) = 55
nt.(6) = 66
---
nt is empty
---

例6-24 文字列で索引付けされている連想配列でのDELETEメソッド

この例では、文字列で索引付けされている連想配列に要素を移入してからすべての要素を削除し、これにより、要素に割り当てられていたメモリーは解放されます。次に、削除した要素を置き換えます(つまり、削除した要素と同じ索引を持つ新しい要素を追加します)。新たに置き換えた要素は、それに対応する削除された要素と同じメモリー量を占有しません。最後に、1つの要素を削除してから、要素の範囲を削除します。プロシージャprint_aa_strは、各操作の効果を表示します。

DECLARE
  TYPE aa_type_str IS TABLE OF INTEGER INDEX BY VARCHAR2(10);
  aa_str  aa_type_str;
 
  PROCEDURE print_aa_str IS
    i  VARCHAR2(10);
  BEGIN
    i := aa_str.FIRST;
 
    IF i IS NULL THEN
      DBMS_OUTPUT.PUT_LINE('aa_str is empty');
    ELSE
      WHILE i IS NOT NULL LOOP
        DBMS_OUTPUT.PUT('aa_str.(' || i || ') = ');
        DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(aa_str(i)), 'NULL'));
        i := aa_str.NEXT(i);
      END LOOP;
    END IF;
 
    DBMS_OUTPUT.PUT_LINE('---');
  END print_aa_str;
 
BEGIN
  aa_str('M') := 13;
  aa_str('Z') := 26;
  aa_str('C') := 3;
  print_aa_str;
 
  aa_str.DELETE;  -- Delete all elements
  print_aa_str;
 
  aa_str('M') := 13;   -- Replace deleted element with same value
  aa_str('Z') := 260;  -- Replace deleted element with new value
  aa_str('C') := 30;   -- Replace deleted element with new value
  aa_str('W') := 23;   -- Add new element
  aa_str('J') := 10;   -- Add new element
  aa_str('N') := 14;   -- Add new element
  aa_str('P') := 16;   -- Add new element
  aa_str('W') := 23;   -- Add new element
  aa_str('J') := 10;   -- Add new element
  print_aa_str;
 
  aa_str.DELETE('C');      -- Delete one element
  print_aa_str;
 
  aa_str.DELETE('N','W');  -- Delete range of elements
  print_aa_str;
 
  aa_str.DELETE('Z','M');  -- Does nothing
  print_aa_str;
END;
/

結果:

aa_str.(C) = 3
aa_str.(M) = 13
aa_str.(Z) = 26
---
aa_str is empty
---
aa_str.(C) = 30
aa_str.(J) = 10
aa_str.(M) = 13
aa_str.(N) = 14
aa_str.(P) = 16
aa_str.(W) = 23
aa_str.(Z) = 260
---
aa_str.(J) = 10
aa_str.(M) = 13
aa_str.(N) = 14
aa_str.(P) = 16
aa_str.(W) = 23
aa_str.(Z) = 260
---
aa_str.(J) = 10
aa_str.(M) = 13
aa_str.(Z) = 260
---
aa_str.(J) = 10
aa_str.(M) = 13
aa_str.(Z) = 260
---

TRIMコレクション・メソッド

TRIMは、VARRAYまたはネストした表の末尾から要素を削除するプロシージャです。

このメソッドには次の形式があります。

  • TRIMは、コレクションに1つ以上の要素が含まれる場合に、末尾から1つの要素を削除します。それ以外の場合は、事前定義の例外SUBSCRIPT_BEYOND_COUNTを呼び出します。

  • TRIM(n)は、コレクションの末尾にn個以上の要素が含まれる場合に、末尾からn個の要素を削除します。それ以外の場合は、事前定義の例外SUBSCRIPT_BEYOND_COUNTを呼び出します。

TRIMは、コレクションの内部サイズを操作します。つまり、DELETEで要素が削除されてもその要素のプレースホルダが保持されている場合、TRIMはその要素が存在するものとみなします。したがって、削除された要素をTRIMで削除することができます。

PL/SQLは切り捨てられた要素のプレースホルダを保持しません。したがって、切り捨てられた要素はコレクションの内部サイズに含まれないため、切り捨てられた要素に有効な値を代入して要素をリストアすることはできません。

注意:

TRIMDELETEの間の相互作用には依存しないでください。ネストした表は、固定サイズの配列のように扱う(DELETEのみを使用する)か、またはスタックのように扱う(TRIMEXTENDのみを使用する)ようにしてください。

例6-25 ネストした表でのTRIMメソッド

この例では、ネストした表の変数を宣言し、6つの要素で初期化した後で、末尾の要素を切り捨て、4番目の要素を削除してから、末尾の2つの要素を切り捨てます(切り捨てる要素の1つは、削除した4番目の要素です)。プロシージャprint_ntは、初期化の後とTRIM操作およびDELETE操作の後に、ネストした表の変数を出力します。型nt_typeおよびプロシージャprint_ntは、例6-6で定義しています。

DECLARE
  nt nt_type := nt_type(11, 22, 33, 44, 55, 66);
BEGIN
  print_nt(nt);

  nt.TRIM;       -- Trim last element
  print_nt(nt);

  nt.DELETE(4);  -- Delete fourth element
  print_nt(nt);

  nt.TRIM(2);    -- Trim last two elements
  print_nt(nt);
END;
/

結果:

nt.(1) = 11
nt.(2) = 22
nt.(3) = 33
nt.(4) = 44
nt.(5) = 55
nt.(6) = 66
---
nt.(1) = 11
nt.(2) = 22
nt.(3) = 33
nt.(4) = 44
nt.(5) = 55
---
nt.(1) = 11
nt.(2) = 22
nt.(3) = 33
nt.(5) = 55
---
nt.(1) = 11
nt.(2) = 22
nt.(3) = 33
---

EXTENDコレクション・メソッド

EXTENDは、VARRAYまたはネストした表の末尾に要素を追加するプロシージャです。

コレクションは空でもかまいませんが、NULLは許可されません。(コレクションを空にしたりNULLのコレクションに要素を追加するには、コンストラクタを使用します。詳細は、「コレクションのコンストラクタ」を参照してください。)

EXTENDメソッドには次の形式があります。

  • EXTENDは、コレクションに1つのNULL要素を追加します。

  • EXTEND(n)は、コレクションにn個のNULL要素を追加します。

  • EXTEND(n,i)は、コレクションにi番目の要素のコピーをn個追加します。

    ノート:

    NOT NULL制約が含まれている要素を持つコレクションに使用できる形式は、EXTEND(n,i)のみです。

EXTENDは、コレクションの内部サイズを操作します。つまり、DELETEで要素が削除されてもその要素のプレースホルダが保持されている場合、EXTENDはその要素が存在するものとみなします。

例6-26 ネストした表でのEXTENDメソッド

この例では、ネストした表の変数を宣言し、3つの要素を使用して初期化した後で、最初の要素のコピーを2つ追加し、次に、5番目(最後)の要素を削除してから、NULL要素を1つ追加します。EXTENDでは、削除された5番目の要素が存在するものとみなされるため、追加されたNULL要素は6番目の要素になります。プロシージャprint_ntは、初期化の後とEXTEND操作およびDELETE操作の後に、ネストした表の変数を出力します。型nt_typeおよびプロシージャprint_ntは、例6-6で定義しています。

DECLARE
  nt nt_type := nt_type(11, 22, 33);
BEGIN
  print_nt(nt);
 
  nt.EXTEND(2,1);  -- Append two copies of first element
  print_nt(nt);
 
  nt.DELETE(5);    -- Delete fifth element
  print_nt(nt);
 
  nt.EXTEND;       -- Append one null element
  print_nt(nt);
END;
/

結果:

nt.(1) = 11
nt.(2) = 22
nt.(3) = 33
---
nt.(1) = 11
nt.(2) = 22
nt.(3) = 33
nt.(4) = 11
nt.(5) = 11
---
nt.(1) = 11
nt.(2) = 22
nt.(3) = 33
nt.(4) = 11
---
nt.(1) = 11
nt.(2) = 22
nt.(3) = 33
nt.(4) = 11
nt.(6) = NULL
---

EXISTSコレクション・メソッド

EXISTSは、VARRAYまたはネストした表の指定された要素が存在するかどうかを表示するファンクションです。

EXISTS(n)は、コレクションにn番目の要素が存在する場合にTRUEを戻し、それ以外の場合はFALSEを戻します。nが範囲外の場合、EXISTSは事前定義の例外SUBSCRIPT_OUTSIDE_LIMITを呼び出さずに、FALSEを戻します。

削除された要素の場合、DELETEによりその要素のプレースホルダが保持されていても、EXISTS(n)FALSEを戻します。

例6-27 ネストした表でのEXISTSメソッド

この例では、ネストした表を4つの要素で初期化した後、2番目の要素を削除して、1番目から6番目の要素の値またはステータスのいずれかを出力します。

DECLARE
  TYPE NumList IS TABLE OF INTEGER;
  n NumList := NumList(1,3,5,7);
BEGIN
  n.DELETE(2); -- Delete second element
 
  FOR i IN 1..6 LOOP
    IF n.EXISTS(i) THEN
      DBMS_OUTPUT.PUT_LINE('n(' || i || ') = ' || n(i));
    ELSE
      DBMS_OUTPUT.PUT_LINE('n(' || i || ') does not exist');
    END IF;
  END LOOP;
END;
/

結果:

n(1) = 1
n(2) does not exist
n(3) = 5
n(4) = 7
n(5) does not exist
n(6) does not exist

FIRSTおよびLASTコレクション・メソッド

FIRSTおよびLASTはファンクションです。

1つ以上の要素を持つコレクションの場合、FIRSTおよびLASTはそれぞれ最初と最後の要素の索引を戻します(削除された要素のプレースホルダがDELETEにより保持されていても、それらの要素は無視されます)。コレクションの要素が1つのみの場合、FIRSTおよびLASTは同じ索引を戻します。コレクションが空の場合、FIRSTLASTNULLを戻します。

ここでのトピック

結合配列に対するFIRSTおよびLASTメソッド

PLS_INTEGERで索引付けされている連想配列の場合、最初の要素および最後の要素は、それぞれ最小および最大の索引を持つ要素です。文字列で索引付けされている連想配列の場合、最初の要素および最後の要素は、それぞれ最小および最大のキー値を持つ要素です。

キー値の順序はソートされています(詳細は、「文字列で索引付けされている連想配列に影響を与えるNLSパラメータ値」を参照してください)。

例6-28 PLS_INTEGERで索引付けされている連想配列のFIRSTとLASTの値

この例では、PLS_INTEGERで索引付けされている連想配列のFIRSTLASTの値を表示してから最初と最後の要素を削除し、再度、FIRSTLASTの値を表示します。

DECLARE
  TYPE aa_type_int IS TABLE OF INTEGER INDEX BY PLS_INTEGER;
  aa_int  aa_type_int;
 
  PROCEDURE print_first_and_last IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('FIRST = ' || aa_int.FIRST);
    DBMS_OUTPUT.PUT_LINE('LAST = ' || aa_int.LAST);
  END print_first_and_last;
 
BEGIN
  aa_int(1) := 3;
  aa_int(2) := 6;
  aa_int(3) := 9;
  aa_int(4) := 12;
 
  DBMS_OUTPUT.PUT_LINE('Before deletions:');
  print_first_and_last;
 
  aa_int.DELETE(1);
  aa_int.DELETE(4);
 
  DBMS_OUTPUT.PUT_LINE('After deletions:');
  print_first_and_last;
END;
/

結果:

Before deletions:
FIRST = 1
LAST = 4
After deletions:
FIRST = 2
LAST = 3

例6-29 文字列で索引付けされている連想配列のFIRSTとLASTの値

この例では、文字列で索引付けされている連想配列のFIRSTLASTの値を表示してから最初と最後の要素を削除し、再度、FIRSTLASTの値を表示します。

DECLARE
  TYPE aa_type_str IS TABLE OF INTEGER INDEX BY VARCHAR2(10);
  aa_str  aa_type_str;
 
  PROCEDURE print_first_and_last IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('FIRST = ' || aa_str.FIRST);
    DBMS_OUTPUT.PUT_LINE('LAST = ' || aa_str.LAST);
  END print_first_and_last;
 
BEGIN
  aa_str('Z') := 26;
  aa_str('A') := 1;
  aa_str('K') := 11;
  aa_str('R') := 18;
 
  DBMS_OUTPUT.PUT_LINE('Before deletions:');
  print_first_and_last;
 
  aa_str.DELETE('A');
  aa_str.DELETE('Z');
 
  DBMS_OUTPUT.PUT_LINE('After deletions:');
  print_first_and_last;
END;
/

結果:

Before deletions:
FIRST = A
LAST = Z
After deletions:
FIRST = K
LAST = R

VARRAYに対するFIRSTおよびLASTメソッド

空ではないVARRAYの場合、FIRSTは常に1を戻します。すべてのVARRAYで、LASTは常にCOUNTに等しくなります。

例6-30 FOR LOOP内のFIRSTおよびLASTによるVARRAYの出力

この例では、team.FIRSTおよびteam.LASTの境界を持つFOR LOOP文を使用して、VARRAYのteamを出力します。VARRAYは常に密であるため、ループの内側のteam(i)は常に存在します。

DECLARE
  TYPE team_type IS VARRAY(4) OF VARCHAR2(15);
  team team_type;
 
  PROCEDURE print_team (heading VARCHAR2)
  IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE(heading);
 
    IF team IS NULL THEN
      DBMS_OUTPUT.PUT_LINE('Does not exist');
    ELSIF team.FIRST IS NULL THEN
      DBMS_OUTPUT.PUT_LINE('Has no members');
    ELSE
      FOR i IN team.FIRST..team.LAST LOOP
        DBMS_OUTPUT.PUT_LINE(i || '. ' || team(i));
      END LOOP;
    END IF;
 
    DBMS_OUTPUT.PUT_LINE('---'); 
  END;
  
BEGIN 
  print_team('Team Status:');
 
  team := team_type();  -- Team is funded, but nobody is on it.
  print_team('Team Status:');
 
  team := team_type('John', 'Mary');  -- Put 2 members on team.
  print_team('Initial Team:');
 
  team := team_type('Arun', 'Amitha', 'Allan', 'Mae');  -- Change team.
  print_team('New Team:');
END;
/

結果:

Team Status:
Does not exist
---
Team Status:
Has no members
---
Initial Team:
1. John
2. Mary
---
New Team:
1. Arun
2. Amitha
3. Allan
4. Mae
---

関連トピック

ネストした表に対するFIRSTおよびLASTメソッド

ネストした表の場合、LASTCOUNTより大きい場合は、中から要素を削除しないかぎり、LASTCOUNTに等しくなります。

例6-31 FOR LOOP内のFIRSTおよびLASTによるネストした表の出力

この例では、team.FIRSTおよびteam.LASTの境界を持つFOR LOOP文を使用して、ネストした表のteamを出力します。ネストした表は疎の場合があるため、team.EXISTS(i)TRUEの場合のみ、FOR LOOP文はteam(i)を出力します。

DECLARE
  TYPE team_type IS TABLE OF VARCHAR2(15);
  team team_type;
 
  PROCEDURE print_team (heading VARCHAR2) IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE(heading);
 
    IF team IS NULL THEN
      DBMS_OUTPUT.PUT_LINE('Does not exist');
    ELSIF team.FIRST IS NULL THEN
      DBMS_OUTPUT.PUT_LINE('Has no members');
    ELSE
      FOR i IN team.FIRST..team.LAST LOOP
        DBMS_OUTPUT.PUT(i || '. ');
        IF team.EXISTS(i) THEN
          DBMS_OUTPUT.PUT_LINE(team(i));
        ELSE
          DBMS_OUTPUT.PUT_LINE('(to be hired)');
        END IF;
      END LOOP;
    END IF;
 
    DBMS_OUTPUT.PUT_LINE('---'); 
  END;
  
BEGIN 
  print_team('Team Status:');
 
  team := team_type();  -- Team is funded, but nobody is on it.
  print_team('Team Status:');
 
  team := team_type('Arun', 'Amitha', 'Allan', 'Mae');  -- Add members.
  print_team('Initial Team:');
 
  team.DELETE(2,3);  -- Remove 2nd and 3rd members.
  print_team('Current Team:');
END;
/

結果:

Team Status:
Does not exist
---
Team Status:
Has no members
---
Initial Team:
1. Arun
2. Amitha
3. Allan
4. Mae
---
Current Team:
1. Arun
2. (to be hired)
3. (to be hired)
4. Mae
---

関連トピック

COUNTコレクション・メソッド

COUNTは、コレクション内の要素の数を戻すファンクションです(削除された要素がDELETEにより保持されていても、それらは無視されます)。

ここでのトピック

VARRAYに対するCOUNTメソッド

VARRAYの場合、COUNTは常にLASTと同じです。VARRAYのサイズを(EXTENDまたはTRIMメソッドを使用して)増減させると、COUNTの値が変更されます。

例6-32 VARRAYのCOUNTとLASTの値

この例では、4つの要素を使用して初期化し、EXTEND(3)に続いてTRIM(5)を実行してから、VARRAYのCOUNTLASTの値を表示します。

DECLARE
  TYPE NumList IS VARRAY(10) OF INTEGER;
  n NumList := NumList(1,3,5,7);
 
  PROCEDURE print_count_and_last IS
  BEGIN
    DBMS_OUTPUT.PUT('n.COUNT = ' || n.COUNT || ', ');
    DBMS_OUTPUT.PUT_LINE('n.LAST = ' || n.LAST);
  END  print_count_and_last;
 
BEGIN
  print_count_and_last;
 
  n.EXTEND(3);
  print_count_and_last;
 
  n.TRIM(5);
  print_count_and_last;
END;
/

結果:

n.COUNT = 4, n.LAST = 4
n.COUNT = 7, n.LAST = 7
n.COUNT = 2, n.LAST = 2

ネストした表に対するCOUNTメソッド

ネストした表の場合、COUNTLASTと同じです。ただし、ネストした表の中から要素を削除すると、COUNTLASTより小さくなります。

例6-33 ネストした表のCOUNTとLASTの値

この例では、4つの要素を使用して初期化し、3番目の要素を削除した後で末尾にNULL要素を2つ追加してから、ネストした表のCOUNTLASTの値を表示します。最後に、1番目から8番目の要素のステータスを出力します。

DECLARE
  TYPE NumList IS TABLE OF INTEGER;
  n NumList := NumList(1,3,5,7);
 
  PROCEDURE print_count_and_last IS
  BEGIN
    DBMS_OUTPUT.PUT('n.COUNT = ' || n.COUNT || ', ');
    DBMS_OUTPUT.PUT_LINE('n.LAST = ' || n.LAST);
  END  print_count_and_last;
 
BEGIN
  print_count_and_last;
 
  n.DELETE(3);  -- Delete third element
  print_count_and_last;
 
  n.EXTEND(2);  -- Add two null elements to end
  print_count_and_last;
 
  FOR i IN 1..8 LOOP
    IF n.EXISTS(i) THEN
      IF n(i) IS NOT NULL THEN
        DBMS_OUTPUT.PUT_LINE('n(' || i || ') = ' || n(i));
      ELSE
        DBMS_OUTPUT.PUT_LINE('n(' || i || ') = NULL');
      END IF;
    ELSE
      DBMS_OUTPUT.PUT_LINE('n(' || i || ') does not exist');
    END IF;
  END LOOP;
END;
/

結果:

n.COUNT = 4, n.LAST = 4
n.COUNT = 3, n.LAST = 4
n.COUNT = 5, n.LAST = 6
n(1) = 1
n(2) = 3
n(3) does not exist
n(4) = 7
n(5) = NULL
n(6) = NULL
n(7) does not exist
n(8) does not exist

LIMITコレクション・メソッド

LIMITは、コレクションに格納可能な要素の最大数を戻すファンクションです。コレクションに要素の最大数がない場合、LIMITNULLを戻します。最大サイズがあるのはVARRAYのみです。

例6-34 様々なコレクション型のLIMITとCOUNTの値

この例では、4つの要素を持つ連想配列、2つの要素を持つVARRAY、3つの要素を持つネストした表について、LIMITCOUNTの値を表示します。

DECLARE
  TYPE aa_type IS TABLE OF INTEGER INDEX BY PLS_INTEGER;
  aa aa_type;                          -- associative array
 
  TYPE va_type IS VARRAY(4) OF INTEGER;
  va  va_type := va_type(2,4);   -- varray
 
  TYPE nt_type IS TABLE OF INTEGER;
  nt  nt_type := nt_type(1,3,5);  -- nested table
 
BEGIN
  aa(1):=3; aa(2):=6; aa(3):=9; aa(4):= 12;
 
  DBMS_OUTPUT.PUT('aa.COUNT = ');
  DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(aa.COUNT), 'NULL'));
 
  DBMS_OUTPUT.PUT('aa.LIMIT = ');
  DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(aa.LIMIT), 'NULL'));
 
  DBMS_OUTPUT.PUT('va.COUNT = ');
  DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(va.COUNT), 'NULL'));
 
  DBMS_OUTPUT.PUT('va.LIMIT = ');
  DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(va.LIMIT), 'NULL'));
 
  DBMS_OUTPUT.PUT('nt.COUNT = ');
  DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(nt.COUNT), 'NULL'));
 
  DBMS_OUTPUT.PUT('nt.LIMIT = ');
  DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(nt.LIMIT), 'NULL'));
END;
/

結果:

aa.COUNT = 4
aa.LIMIT = NULL
va.COUNT = 2
va.LIMIT = 4
nt.COUNT = 3
nt.LIMIT = NULL

PRIORおよびNEXTコレクション・メソッド

PRIORおよびNEXTは、コレクション内を前後に移動できるファンクションです(削除された要素がDELETEにより保持されていても、それらは無視されます)。このメソッドは、疎コレクション内の移動に便利です。

索引を指定すると次のようになります:

  • 先行する要素が存在する場合、PRIORはそのコレクション要素の索引を戻します。存在しない場合、PRIORNULLを戻します。

    任意のコレクションcの場合、c.PRIOR(c.FIRST)NULLを戻します。

  • 後続の要素が存在する場合、NEXTはそのコレクション要素の索引を戻します。存在しない場合、NEXTNULLを戻します。

    任意のコレクションcの場合、c.NEXT(c.LAST)NULLを戻します。

指定された索引が存在していなくてもかまいません。ただし、コレクションcがVARRAYで、索引がc.LIMITより大きい場合は次のようになります。

  • c.PRIOR(index)c.LASTを戻します。

  • c.NEXT(index)NULLを戻します。

たとえば:

DECLARE
  TYPE Arr_Type IS VARRAY(10) OF NUMBER;
  v_Numbers Arr_Type := Arr_Type();
BEGIN
  v_Numbers.EXTEND(4);
 
  v_Numbers (1) := 10;
  v_Numbers (2) := 20;
  v_Numbers (3) := 30;
  v_Numbers (4) := 40;
 
  DBMS_OUTPUT.PUT_LINE(NVL(v_Numbers.prior (3400), -1));
  DBMS_OUTPUT.PUT_LINE(NVL(v_Numbers.next (3400), -1));
END;
/

結果:

4
-1

文字列で索引付けされている連想配列の場合、前の索引および次の索引はキー値で決まり、キー値の順序はソートされています(詳細は、「文字列で索引付けされている連想配列に影響を与えるNLSパラメータ値」を参照してください)。例6-1では、FIRSTNEXTおよびWHILE LOOP文を使用して連想配列の要素を出力しました。

例6-35 PRIORおよびNEXTメソッド

この例では、ネストした表を6つの要素で初期化した後、4番目の要素を削除して、1番目から7番目の要素のPRIORNEXTの値を表示します。4番目と7番目の要素は存在しません。値はNULLですが、2番目の要素は存在します。

DECLARE
  TYPE nt_type IS TABLE OF NUMBER;
  nt nt_type := nt_type(18, NULL, 36, 45, 54, 63);
 
BEGIN
  nt.DELETE(4);
  DBMS_OUTPUT.PUT_LINE('nt(4) was deleted.');
 
  FOR i IN 1..7 LOOP
    DBMS_OUTPUT.PUT('nt.PRIOR(' || i || ') = ');
    DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(nt.PRIOR(i)), 'NULL'));

    DBMS_OUTPUT.PUT('nt.NEXT(' || i || ')  = ');
    DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(nt.NEXT(i)), 'NULL'));
  END LOOP;
END;
/

結果:

nt(4) was deleted.
nt.PRIOR(1) = NULL
nt.NEXT(1)  = 2
nt.PRIOR(2) = 1
nt.NEXT(2)  = 3
nt.PRIOR(3) = 2
nt.NEXT(3)  = 5
nt.PRIOR(4) = 3
nt.NEXT(4)  = 5
nt.PRIOR(5) = 3
nt.NEXT(5)  = 6
nt.PRIOR(6) = 5
nt.NEXT(6)  = NULL
nt.PRIOR(7) = 6
nt.NEXT(7)  = NULL

例6-36 疎であるネストした表の要素の出力

この例では、疎であるネストした表の要素を、FIRSTNEXTを使用して最初から最後まで出力し、LASTPRIORを使用して最後から最初まで出力します。

DECLARE
  TYPE NumList IS TABLE OF NUMBER;
  n NumList := NumList(1, 2, NULL, NULL, 5, NULL, 7, 8, 9, NULL);
  idx INTEGER;
 
BEGIN
  DBMS_OUTPUT.PUT_LINE('First to last:');
  idx := n.FIRST;
  WHILE idx IS NOT NULL LOOP
    DBMS_OUTPUT.PUT('n(' || idx || ') = ');
    DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(n(idx)), 'NULL'));
    idx := n.NEXT(idx);
  END LOOP;
    
  DBMS_OUTPUT.PUT_LINE('--------------');
 
  DBMS_OUTPUT.PUT_LINE('Last to first:');
  idx := n.LAST;
  WHILE idx IS NOT NULL LOOP
    DBMS_OUTPUT.PUT('n(' || idx || ') = ');
    DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(n(idx)), 'NULL'));
    idx := n.PRIOR(idx);
  END LOOP;
END;
/

結果:

First to last:
n(1) = 1
n(2) = 2
n(3) = NULL
n(4) = NULL
n(5) = 5
n(6) = NULL
n(7) = 7
n(8) = 8
n(9) = 9
n(10) = NULL
--------------
Last to first:
n(10) = NULL
n(9) = 9
n(8) = 8
n(7) = 7
n(6) = NULL
n(5) = 5
n(4) = NULL
n(3) = NULL
n(2) = 2
n(1) = 1