すべてのプロダクト
Search
ドキュメントセンター

PolarDB:連想配列

最終更新日:May 29, 2024

連想配列は、一意のキーを値に関連付けるコレクションの一種です。 連想配列は、整数または文字列をキーとして使用できます。

連想配列には次の特徴があります。

  • 連想配列型は、その配列型の配列変数を宣言する前に定義する必要があります。 データ操作は、配列変数を使用して実装されます。
  • 配列変数が宣言されると、空の連想配列が作成されます。 配列要素に値を割り当てることができます。
  • 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次元連想配列の機能を実装できます。
        タイプ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; 
    2次元連想配列がサポートされている場合、次の例に示すように、中間テーブルv_table1を使用する代わりに、2次元の添字を使用してv_table2の要素に値を割り当てることができます。
    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; 
    前の匿名ブロックが実行された後、次のサンプル出力が生成されます。
    ERROR: 現在、パッケージなしの連想配列のみであり、is TABLE型はレコード型ではありません。コンテキスト: 11
    行目近くのSPL関数「inline_code_block」のコンパイル
    ネストされたテーブルまたはバーレイには、次の例
    に示すように、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は多次元連想配列ではありません