連想配列の使用
連想配列は、コレクションの1つのタイプです。
コレクションについて
コレクションは、指定した順序と同じ型の要素を格納するPL/SQLのコンポジット変数で、一次元配列に似ています。コレクションの内部コンポーネントは、要素と呼ばれます。各要素には、コレクションでの位置を示す一意のサブスクリプトが含まれます。
コレクション要素にアクセスするには、collection_name(element_subscript)のような添字表記を使用します。
コレクション要素はスカラー変数のように処理できます。また、コレクション全体をサブプログラムのパラメータとして渡すこともできます(送信または受信サブプログラムのどちらもスタンドアロンのサブプログラムでない場合)。
コレクション・メソッドは、組込みPL/SQLサブプログラムで、 コレクションに関する情報を戻すか、 コレクションに対する操作を実行します。コレクション・メソッドを起動するには、ドット表記法: collection_name.method_nameを使用します。たとえば、collection_name.COUNTはコレクション内の要素の数を戻します。
PL/SQLには、次の3種類のコレクションがあります。
-
連想配列(以前の「PL/SQL表」または「索引付き表」)
-
ネストされた表
-
可変配列(varrays)
このドキュメントでは、連想配列についてのみ説明します。
関連情報:
-
PL/SQLのコレクションの種類に関する詳細は、Oracle Database PL/SQL言語リファレンスを参照してください。
-
コレクション・メソッドの詳細は、Oracle Database PL/SQL言語リファレンスを参照
連想配列について
連想配列は、キー/値のペアのバインドされていないセットです。各キーは固有で、該当する値を保持する要素のサブスクリプトとして使用されます。このため、配列内の場所を知らなくても、配列をトラバースせずに要素にアクセスできます。
キーのデータ型は、PLS_INTEGERまたはVARCHAR2 (長さ)です。
キーのデータ型がPLS_INTEGERで、連想配列が整数で索引付けされ、稠密(つまり、要素間に差異がない)である場合、最初と最後の要素の間のすべての要素が定義されており、それぞれに値があります(値はNULLの場合もあります)。
キー・タイプがVARCHAR2 (長さ)の場合、連想配列は文字列(2文字)で索引付けされて、スパースです。つまり、要素間に差異がある可能性があります。
稠密な連想配列をトラバースする場合、要素間の差異を考慮する必要はありません。スパースな連想配列をトラバースする場合は、要素間の差異を考慮する必要があります。
連想配列の要素に値を割り当てるには、代入演算子を使用できます。
array_name(key) := value
キーが配列にない場合、代入文によって配列にキーと値のペアが追加されます。それ以外の場合、この文はarray_name(key)の値を値に変更します。
連想配列は、データを一時的に格納する場合に有用です。表が必要とするディスク領域またはネットワーク操作を使用しません。ただし、連想配列は、データを一時的に格納する用途のため、DML文で操作できません。
パッケージ内で連想配列を宣言し、パッケージ本体の変数に値を割り当てると、連想配列はデータベース・セッションの存続期間中に存在します。そうでない場合は、宣言したサブプログラムの存続期間中に存在します。
関連項目:連想配列の詳細は『Oracle Database PL/SQL言語リファレンス』を参照してください。
連想配列の宣言
連想配列を宣言するには、連想配列の型を宣言し、その型の変数を宣言します。
次のコードは、最も単純な構文を示しています。
TYPE array_type IS TABLE OF element_type INDEX BY key_type;
array_name array_type;
連想配列を宣言する効果的な方法は、次の手順を実行して、カーソルを使用することです。この手順では、最も単純な形式で必要な各文を使用し、複雑な構文への参照も提示します。
カーソルを使用して連想配列を宣言するには:
-
宣言部で次を実行します。
-
カーソルを宣言します。
CURSOR cursor_name IS query;宣言カーソルの宣言構文の詳細は、Oracle Database PL/SQL言語リファレンスに関する項を参照してください。
-
連想配列の型を宣言します。
TYPE array_type IS TABLE OF cursor_name%ROWTYPE INDEX BY { PLS_INTEGER | VARCHAR2 length }連想配列の型の構文の詳細は、Oracle Database PL/SQL言語リファレンスに関する項を参照してください。
-
その型の連想配列の変数を宣言します。
array_name array_type;変数値の宣言構文の詳細は、Oracle Database PL/SQL言語リファレンスに関する項を参照してください。
-
例5-9では、前述の手順を使用して2つの連想配列employees_jobsおよびjobs_を宣言し、カーソルを使用せずに3つ目の連想配列job_titlesを宣言します。1つ目と2つ目の配列は整数で索引付けされ、3つ目は文字列によって索引付けされます。
ノート: employees_jobs_cursorの宣言内のORDER BY句によって、連想配列employee_jobsの要素の格納順が決定されます。
例5-9 連想配列の宣言
DECLARE
-- Declare cursor:
CURSOR employees_jobs_cursor IS
SELECT FIRST_NAME, LAST_NAME, JOB_ID
FROM EMPLOYEES
ORDER BY JOB_ID, LAST_NAME, FIRST_NAME;
-- Declare associative array type:
TYPE employees_jobs_type IS TABLE OF employees_jobs_cursor%ROWTYPE
INDEX BY PLS_INTEGER;
-- Declare associative array:
employees_jobs employees_jobs_type;
-- Use same procedure to declare another associative array:
CURSOR jobs_cursor IS
SELECT JOB_ID, JOB_TITLE
FROM JOBS;
TYPE jobs_type IS TABLE OF jobs_cursor%ROWTYPE
INDEX BY PLS_INTEGER;
jobs_ jobs_type;
-- Declare associative array without using cursor:
TYPE job_titles_type IS TABLE OF JOBS.JOB_TITLE%TYPE
INDEX BY JOBS.JOB_ID%TYPE; -- jobs.job_id%type is varchar2(10)
job_titles job_titles_type;
BEGIN
NULL;
END;
/
関連情報:
-
連想配列宣言の構文については、『Oracle Database PL/SQL言語リファレンス』を参照してください
連想配列の移入
通常、稠密な連想配列を移入する最も効率的な方法は、SELECT文にBULK COLLECT INTO句を使用することです。
ノート:稠密な連想配列が非常に大きいため、SELECT文が大きすぎてメモリーに収まらない結果セットを戻す場合、SELECT文を使用しないでください。かわりに、カーソルおよびFETCH文にBULK COLLECT INTO句およびLIMIT句を移入してください。BULK COLLECT INTO句を含むFETCH文の使用の詳細は、Oracle Database PL/SQL言語リファレンスに関する項を参照してください。
SELECT文を使用して、スパースな連想配列(「連想配列を宣言」のjob_titlesなど)を移入できません。そのかわり、ループ文内部に代入文を使用する必要があります。ループ文の詳細は、プログラム・フローの制御を参照してください。例5-10では、SELECT文を使用して、整数によって索引付けされるemployees_jobsおよびjobs_を連想配列に移入します。次に、FOR LOOP文内部の代入文を使用して、文字列で索引付けされる連想配列job_titlesを移入します。
例5-10 連想配列の移入
-- Declarative part from Example 5-9 goes here.
BEGIN
-- Populate associative arrays indexed by integer:
SELECT FIRST_NAME, LAST_NAME, JOB_ID BULK COLLECT INTO employees_jobs
FROM EMPLOYEES ORDER BY JOB_ID, LAST_NAME, FIRST_NAME;
SELECT JOB_ID, JOB_TITLE BULK COLLECT INTO jobs_ FROM JOBS;
-- Populate associative array indexed by string:
FOR i IN 1..jobs_.COUNT() LOOP
job_titles(jobs_(i).job_id) := jobs_(i).job_title;
END LOOP;
END;
/
関連項目: カーソルについて
稠密な連想配列のトラバース
稠密な連想配列(整数による索引付け)には、要素間の差異がなく、最初と最後の要素の間のすべての要素が定義されていて、それぞれに値があります(値はNULLの場合もあります)。
例5-11のように、FOR LOOP文で稠密な配列を横断できます。
例5-10の実行可能部分に挿入すると、例5-11の実行可能部分に挿入すると、employees_jobs配列を移入するコードの後に、employees_jobs配列の要素を、格納された順序で出力します。格納順序は、employees_jobsを宣言するために使用されたemployees_jobs_cursor宣言のORDER BY句によって決定されました(例5-9を参照)。
FOR LOOP文の上限employees_jobs.COUNTは、配列内の要素の数を戻すコレクション・メソッドを起動します。COUNTの詳細は、『Oracle Database PL/SQL言語リファレンス』に関する項を参照してください。
例5-11 稠密連想配列の横断
-- Code that populates employees_jobs must precede this code:
FOR i IN 1..employees_jobs.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(
RPAD(employees_jobs(i).first_name, 23) ||
RPAD(employees_jobs(i).last_name, 28) || employees_jobs(i).job_id);
END LOOP;
結果:
William Gietz AC_ACCOUNT
Shelley Higgins AC_MGR
Jennifer Whalen AD_ASST
Steven King AD_PRES
Lex De Haan AD_VP
Neena Kochhar AD_VP
John Chen FI_ACCOUNT
...
Jose Manuel Urman FI_ACCOUNT
Nancy Greenberg FI_MGR
Susan Mavris HR_REP
David Austin IT_PROG
...
Valli Pataballa IT_PROG
Michael Hartstein MK_MAN
Pat Fay MK_REP
Hermann Baer PR_REP
Shelli Baida PU_CLERK
...
Sigal Tobias PU_CLERK
Den Raphaely PU_MAN
Gerald Cambrault SA_MAN
...
Eleni Zlotkey SA_MAN
Ellen Abel SA_REP
...
Clara Vishney SA_REP
Sarah Bell SH_CLERK
...
Peter Vargas ST_CLERK
Adam Fripp ST_MAN
...
Matthew Weiss ST_MAN
スパースな連想配列のトラバース
スパースな連想配列(文字列による索引付け)は、要素間に差異がある可能性があります。
例5-12のように、WHILE LOOP文で横断できます。
例5-12でコードを実行し、job_titles配列の要素を出力するには、次のステップを実行します。
-
例5-9の宣言部分の終わりに、次の変数宣言を挿入してください。
i jobs.job_id%TYPE;
例5-12 スパース連想配列の横断
/* Declare this variable in declarative part:
i jobs.job_id%TYPE;
Add this code to the executable part,
after code that populates job_titles:
*/
i := job_titles.FIRST;
WHILE i IS NOT NULL LOOP
DBMS_OUTPUT.PUT_LINE(RPAD(i, 12) || job_titles(i));
i := job_titles.NEXT(i);
END LOOP;
結果:
AC_ACCOUNT Public Accountant
AC_MGR Accounting Manager
AD_ASST Administration Assistant
AD_PRES President
AD_VP Administration Vice President
FI_ACCOUNT Accountant
FI_MGR Finance Manager
HR_REP Human Resources Representative
IT_PROG Programmer
MK_MAN Marketing Manager
MK_REP Marketing Representative
PR_REP Public Relations Representative
PU_CLERK Purchasing Clerk
PU_MAN Purchasing Manager
SA_MAN Sales Manager
SA_REP Sales Representative
SH_CLERK Shipping Clerk
ST_CLERK Stock Clerk
ST_MAN Stock Manager
Example 5-12 includes two collection method invocations, job_titles.FIRST and job_titles.NEXT(i). job_titles.FIRST returns the first element of job_titles, and job_titles.NEXT(i) returns the subscript that succeeds i. FIRSTの詳細は、『Oracle Database PL/SQL言語リファレンス』に関する項を参照してください。NEXTの詳細は、『Oracle Database PL/SQL言語リファレンス』に関する項を参照してください。