連想配列は、一意のキーを値に関連付けるコレクションの一種です。 連想配列は、整数または文字列をキーとして使用できます。
連想配列には次の特徴があります。
- 連想配列型は、その配列型の配列変数を宣言する前に定義する必要があります。 データ操作は、配列変数を使用して実装されます。
- 配列変数が宣言されると、空の連想配列が作成されます。 配列要素に値を割り当てることができます。
- INDEXBY BINARY_INTEGERまたはPLS_INTEGERが指定されている場合、連想配列のキーは、負の整数、正の整数、またはゼロにすることができます。
- INDEXBY VARCHAR2が指定されている場合、連想配列のキーは文字列になります。
- 配列内の要素数の制限は事前に定義されていません。 要素が追加されるにつれて、数は動的に増加します。
- 連想配列はスパースである可能性があります。つまり、キーへの値の割り当てにギャップが存在する可能性があります。
- 値が割り当てられていない配列要素を参照しようとすると、例外が発生します。
タイプはのテーブルです... INDEX BYステートメントは、連想配列型を定義するために使用されます。
TYPE assoctypeは {datatype | rectype | objtype} のテーブルです
インデックスBY { BINARY_INTEGER | PLS_INTEGER | VARCHAR2(n) };
assotypeは、配列型の識別子を指定します。 datatypeは、VARCHAR2やNUMBERなどのスカラーデータ型を指定します。 rectypeは、定義済みのレコードタイプを指定します。 objtypeは、定義済みのオブジェクトタイプを指定します。 nは文字キーの最大長を指定します。
配列の型を使用するには、配列型の変数を宣言する必要があります。 次の構文を使用して、配列変数を宣言します。
配列assoctype
上記の構文では、arrayは連想配列に割り当てられている識別子を示します。 assotypeは、以前に定義された配列型の識別子を示します。
次の構文を使用して、配列の要素を参照できます。
array(n)[.field ]
arrayは、以前に宣言された配列の識別子を示します。 nは, INDEX by句で指定したデータ型の値を示します。 配列がレコード型またはオブジェクト型から定義されている場合、[.field] は、配列型が定義されているオブジェクト型内のレコード型または属性内で定義されている個々のフィールドを参照する必要があります。 レコード全体を参照するには [.field] を省略します。
次のコードでは、empテーブルから最初の10人の従業員名を読み取り、それらを配列に格納してから、配列のデータを表示する方法の例を示します。
DECLARE
TYPE emp_arr_typはBINARY_INTEGERによるVARCHAR2(10) インデックスのテーブルです。
emp_arr emp_arr_typ;
CURSOR emp_curは、ROWNUM <= 10のempから選択されます。
i INTEGER := 0;
開始
FOR r_emp IN emp_cur LOOP
i := i + 1;
emp_arr(i) := r_emp.ename;
END LOOP;
FOR j IN 1 .. 10ループ
DBMS_OUTPUT.PUT_LINE(emp_arr(j));
エンドループ;
エンド;
上記のコードを実行すると、次のサンプル出力が生成されます。
スミス
アレン
ワード
ジョーンズ
マーティン
ブレイク
クラーク
スコット
キング
ターナー
この例は、配列定義でレコード型を使用するように変更できます。
DECLARE
タイプemp_rec_typは記録されています (
empno NUMBER(4),
ename VARCHAR2 (10)
);
TYPE emp_arr_typはBINARY_INTEGERによるemp_rec_typインデックスのテーブルです。
emp_arr emp_arr_typ;
CURSOR emp_curはSELECT empno、ename FROM WHERE ROWNUM <= 10です。
i INTEGER := 0;
開始
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
FOR r_emp IN emp_cur LOOP
i := i + 1;
emp_arr(i).empno := r_emp.empno;
emp_arr(i).ename := r_emp.ename;
END LOOP;
FOR j IN 1 .. 10ループ
DBMS_OUTPUT.PUT_LINE(emp_arr(j).empno | | '|
emp_arr(j).ename);
エンドループ;
エンド;
上記の匿名ブロックが実行されると、次のサンプル出力が生成されます。
EMPNO ENAME
----- -------
7369スミス
7499アレン
7521ワード
7566ジョーンズ
7654マーティン
7698 BLAKE
7782 CLARK
7788スコット
7839キング
7844ターナー
この例では、emp_rec_typレコードタイプを使用する代わりに、emp % ROWTYPE属性を使用してemp_arr_typを定義するようにさらに変更できます。 以下にコードの例を示します。
DECLARE
TYPE emp_arr_typはBINARY_INTEGERによるemp % ROWTYPEインデックスのテーブルです。
emp_arr emp_arr_typ;
CURSOR emp_curはSELECT empno、ename FROM WHERE ROWNUM <= 10です。
i INTEGER := 0;
開始
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
FOR r_emp IN emp_cur LOOP
i := i + 1;
emp_arr(i).empno := r_emp.empno;
emp_arr(i).ename := r_emp.ename;
END LOOP;
FOR j IN 1 .. 10ループ
DBMS_OUTPUT.PUT_LINE(emp_arr(j).empno | | '|
emp_arr(j).ename);
エンドループ;
エンド;
この場合、サンプル出力は前の例と同じです。
レコードの各フィールドを個別に割り当てる代わりに、レコードレベルの割り当てをr_empからemp_arrに行うことができます。
DECLARE
タイプemp_rec_typは記録されています (
empno NUMBER(4),
ename VARCHAR2 (10)
);
TYPE emp_arr_typはBINARY_INTEGERによるemp_rec_typインデックスのテーブルです。
emp_arr emp_arr_typ;
CURSOR emp_curはSELECT empno、ename FROM WHERE ROWNUM <= 10です。
i INTEGER := 0;
開始
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
FOR r_emp IN emp_cur LOOP
i := i + 1;
emp_arr(i) := r_emp;
END LOOP;
FOR j IN 1 .. 10ループ
DBMS_OUTPUT.PUT_LINE(emp_arr(j).empno | | '|
emp_arr(j).ename);
エンドループ;
エンド;
連想配列のキーは、次の例に示すように文字列にすることができます。
DECLARE
タイプjob_arr_typはVARCHAR2(9) による番号インデックスのテーブルです。
job_arr job_arr_typ;
開始
job_arr('ANALYST') := 100;
job_arr('CLERK') := 200;
job_arr('MANAGER') := 300;
job_arr('SALESMAN') := 400;
job_arr('PRESIDENT') := 500;
DBMS_OUTPUT.PUT_LINE('ANALYST : '| | job_arr('ANALYST'));
DBMS_OUTPUT.PUT_LINE('CLERK : '| | job_arr('CLERK'));
DBMS_OUTPUT.PUT_LINE('MANAGER : '| | job_arr('MANAGER'));
DBMS_OUTPUT.PUT_LINE('SALESMAN : '| | job_arr('SALESMAN'));
DBMS_OUTPUT.PUT_LINE('PRESIDENT: '| | job_arr('PRESIDENT'));
エンド;
アナリスト: 100
CLERK : 200
マネージャー: 300
SALESMAN : 400
大統領: 500
二次元連想配列
2次元連想配列は、ネストされた連想配列です。 2次元連想配列の値は1次元配列です。 2つのキーを使用して、最も内側の連想配列の要素を関連付けることができます。 2次元アソシアティブ配列の基本的な特性は、アソシアティブ配列と同じである。
- 2次元連想配列でサポートされているシナリオ1次元連想配列のみがサポートされている場合は、中間テーブルを使用して、次の例
2次元連想配列がサポートされている場合、次の例に示すように、中間テーブルv_table1を使用する代わりに、2次元の添字を使用してv_table2の要素に値を割り当てることができます。に示すように、2次元連想配列の機能を実装できます。 タイプTB1はvarchar(10) によるvarchar(10) indexのテーブルです。 タイプTB2はvarchar(10) によるTB1インデックスのテーブルです。 v_table1 TB1; v_table2 TB2; 開始 v_table1('a') := 1; v_table1('b') := 2; v_table1('c') := 3; v_table2('a') := v_table1; END;
DECLARE タイプTB1はvarchar(10) によるvarchar(10) indexのテーブルです。 タイプTB2はvarchar(10) によるTB1インデックスのテーブルです。 v_table2 TB2; 開始 v_table2('a')('a') := 1; v_table2('a')('b') := 2; v_table2('a')('c') := 3; エンド;
- 例次の例は、2次元連想配列を使用する方法を示しています。
前の匿名ブロックが実行されると、次のサンプル出力が生成されます。-- dim-2連想配列の例 DECLARE type_row型はvarchar(10) によるvarchar(10) indexの表です。 型type_tableはvarchar(10) によるtype_rowインデックスのテーブルです。 v_table type_table; i varchar2(64); i_2 varchar2(64); 開始 v_table('a')('b') := 10; v_table('a')('c') := 11; v_table('z')('b') := 12; v_table('z')('c') := 13; i := v_table.FIRST; 私はNULLループではありません i_2 := v_table(i).FIRST; i_2はNULLループではありません dbms_output.put_line(i | | | '' | | i_2 | | '-' | | | TO_CHAR(v_table(i)(i_2))); i_2 := v_table(i).NEXT(i_2); END LOOP; i := v_table.NEXT(i); エンドループ; END;
a b-10 c-11 z b-12 z c-13
- 収集方法2次元連想配列は、COUNT、FIRST、LAST、NEXT、PRIOR、およびEXISTSの収集方法をサポートします。
次のメソッドを使用して、COUNTなどのパラメーターを取得しない収集メソッドを呼び出すことができます。array_dim2(n) 次のメソッドを使用して、NEXTなどの1つのパラメーターのみを受け取る収集メソッドを呼び出すことができます。array_dim2(n).op(n)
説明- array_dim2: 以前に宣言された2次元連想配列の識別子を示します。
- n:
INDEX by
句で指定されたデータ型の値を示します。 - op: 収集方法を示します。
次のコードは、2次元連想配列で収集メソッドを呼び出す方法の例を示しています。
前の匿名ブロックが実行されると、次のサンプル出力が生成されます。タイプTB1はvarchar(10) によるvarchar(10) indexのテーブルです。 タイプTB2はvarchar(10) によるTB1インデックスのテーブルです。 タイプTB3はvarchar(10) によるTB2インデックスの表です。 v_table TB2; v_table3 TB3; 開始 v_table('a')('b') := 10; v_table('b')('c') := 11; v_table('c')('b') := 12; v_table('d')('c') := 13; v_table3('a') := v_table; dbms_output.put_line(v_table3('a').COUNT); dbms_output.put_line(v_table3('a').FIRST); dbms_output.put_line(v_table3('a').LAST); dbms_output.put_line(v_table3('a').NEXT(v_table3('a').FIRST)); dbms_output.put_line(v_table3('a').prior(v_table3('a').LAST)); dbms_output.put_line(v_table3('a').exists(v_table3('a').FIRST)); END;
4 a d b c t
- 2次元連想配列でサポートされていないシナリオ
2次元のサブスクリプトは、2次元の連想配列でのみサポートされますが、ネストされたテーブルやvarrayではサポートされません。
2次元連想配列は、次の例に示すように、レコードタイプをサポートしていません
前の匿名ブロックが実行された後、次のサンプル出力が生成されます。。 タイプemp_typは記録されています ( ename varchar(10) 、 first varchar (10) ); タイプTBはvarchar(10) によるemp_typインデックスのテーブルです。 タイプTB2はvarchar(10) によるTBインデックスのテーブルです。 mytable TB2; myrecord emp_typ; 開始 mytable('a')('b') := myrecord; END;
行目近くのSPL関数「inline_code_block」のコンパイルERROR: 現在、パッケージなしの連想配列のみであり、is TABLE型はレコード型ではありません。コンテキスト: 11
ネストされたテーブルまたはバーレイには、次の例
上記の匿名ブロックが実行された後、次のサンプル出力が生成されます。に示すように、2次元の連想配列を含めることはできません。 タイプTB1は番号による番号インデックスのテーブルです。 タイプTB2は番号によるTB1インデックスのテーブルです。 タイプTB3はTB2のテーブルです; v_table2 TB2; v_table3 TB3; 開始 v_table2(1)(1) := 1; v_table2(1)(2) := 2; v_table2(2)(3) := 3; v_table2(2)(4) := 4; v_table3 := TB3(v_table2); END;
ERROR: ネストされたテーブルとVarrayは多次元連想配列ではありません