連想配列
連想配列(旧称はPL/SQL表または索引付き表)は、キーと値のペアのセットです。各キーは一意の索引であり、構文variable_name
(
index
)
を使用して、関連する値を検索するために使用されます。
索引
のデータ型には、文字列型(VARCHAR2
、VARCHAR
、STRING
またはLONG
)またはPLS_INTEGER
を使用できます。索引は、作成された順序ではなく、ソートされた順序で格納されます。文字列型の場合、ソートの順序は初期化パラメータNLS_SORT
およびNLS_COMP
で決定されます。
データベース表と同様に、連想配列には次の特性があります。
-
移入するまで空である(ただし、NULLではない)
-
数が指定されていない要素を保持できる(要素の位置を知らなくてもアクセスできる)
連想配列には、データベース表とは異なる次の特性があります。
-
ディスク領域またはネットワーク操作が不要
-
DML文では操作できない
ここでのトピック
関連項目:
-
表6-1に、連想配列の特性の概要を示します
-
結合配列型の定義の構文は、「assoc_array_type_def ::=」を参照してください
例6-1 文字列で索引付けされている連想配列
この例では、文字列で索引付けされる連想配列型を定義し、この型の変数を宣言して3つの要素を変数に移入し、1つの要素の値を変更した後に値を(作成された順序ではなくソートされた順序で)出力します。(FIRST
およびNEXT
はコレクション・メソッドです。詳細は「コレクション・メソッド」を参照してください。)
Live SQL:
この例は、Oracle Live SQLの「文字列で索引付けされている連想配列」で表示および実行できます
DECLARE
-- Associative array indexed by string:
TYPE population IS TABLE OF NUMBER -- Associative array type
INDEX BY VARCHAR2(64); -- Indexed by string
city_population population; -- Associative array variable
i VARCHAR2(64); -- Scalar variable
BEGIN
-- Add elements (key-value pairs) to associative array:
city_population('Smallville') := 2000;
city_population('Midland') := 750000;
city_population('Megalopolis') := 1000000;
-- Change value associated with key 'Smallville':
city_population('Smallville') := 2001;
-- Print associative array:
i := city_population.FIRST; -- Get first element of array
WHILE i IS NOT NULL LOOP
DBMS_Output.PUT_LINE
('Population of ' || i || ' is ' || city_population(i));
i := city_population.NEXT(i); -- Get next element of array
END LOOP;
END;
/
結果:
Population of Megalopolis is 1000000
Population of Midland is 750000
Population of Smallville is 2001
例6-2 PLS_INTEGERで索引付けされている連想配列を戻すファンクション
この例では、PLS_INTEGER
で索引付けされている連想配列型と、その型の連想配列を戻すファンクションを定義します。
Live SQL:
この例は、Oracle Live SQLの「PLS_INTEGERで索引付けされている連想配列を戻すファンクション」で表示および実行できます
DECLARE
TYPE sum_multiples IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;
n PLS_INTEGER := 5; -- number of multiples to sum for display
sn PLS_INTEGER := 10; -- number of multiples to sum
m PLS_INTEGER := 3; -- multiple
FUNCTION get_sum_multiples (
multiple IN PLS_INTEGER,
num IN PLS_INTEGER
) RETURN sum_multiples
IS
s sum_multiples;
BEGIN
FOR i IN 1..num LOOP
s(i) := multiple * ((i * (i + 1)) / 2); -- sum of multiples
END LOOP;
RETURN s;
END get_sum_multiples;
BEGIN
DBMS_OUTPUT.PUT_LINE (
'Sum of the first ' || TO_CHAR(n) || ' multiples of ' ||
TO_CHAR(m) || ' is ' || TO_CHAR(get_sum_multiples (m, sn)(n))
);
END;
/
結果:
Sum of the first 5 multiples of 3 is 45
連想配列の定数の宣言
連想配列定数を宣言する場合、修飾式を使用して、簡潔な形式の初期値で連想配列を初期化できます。
コンストラクタの詳細は、「コレクションのコンストラクタ」を参照してください。
例6-3 連想配列の定数の宣言
修飾式の索引関連付け集計を使用して、定数連想配列の索引式および値式を初期化できます。
DECLARE
TYPE My_AA IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
v CONSTANT My_AA := My_AA(-10=>'-ten', 0=>'zero', 1=>'one', 2=>'two', 3 => 'three', 4 => 'four', 9 => 'nine');
BEGIN
DECLARE
Idx PLS_INTEGER := v.FIRST();
BEGIN
WHILE Idx IS NOT NULL LOOP
DBMS_OUTPUT.PUT_LINE(TO_CHAR(Idx, '999')||LPAD(v(Idx), 7));
Idx := v.NEXT(Idx);
END LOOP;
END;
END;
/
Oracle Databaseリリース18cより前では、同じ結果を得るには、連想配列コンストラクタの関数を作成する必要がありました。両方の例を比較すると、修飾式によってよりコンパクトにできることで、プログラムの明確性と開発者の生産性が向上することがわかります。
Live SQL:
この例は、Oracle Live SQLの「連想配列の定数の宣言」で表示および実行できます
CREATE OR REPLACE PACKAGE My_Types AUTHID CURRENT_USER IS
TYPE My_AA IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
FUNCTION Init_My_AA RETURN My_AA;
END My_Types;
/
CREATE OR REPLACE PACKAGE BODY My_Types IS
FUNCTION Init_My_AA RETURN My_AA IS
Ret My_AA;
BEGIN
Ret(-10) := '-ten';
Ret(0) := 'zero';
Ret(1) := 'one';
Ret(2) := 'two';
Ret(3) := 'three';
Ret(4) := 'four';
Ret(9) := 'nine';
RETURN Ret;
END Init_My_AA;
END My_Types;
/
DECLARE
v CONSTANT My_Types.My_AA := My_Types.Init_My_AA();
BEGIN
DECLARE
Idx PLS_INTEGER := v.FIRST();
BEGIN
WHILE Idx IS NOT NULL LOOP
DBMS_OUTPUT.PUT_LINE(TO_CHAR(Idx, '999')||LPAD(v(Idx), 7));
Idx := v.NEXT(Idx);
END LOOP;
END;
END;
/
結果:
-10 -ten
0 zero
1 one
2 two
3 three
4 four
9 nine
文字列で索引付けされている結合配列に影響を与えるNLSパラメータ値
文字列で索引付けされている連想配列は、NLS_SORT
、NLS_COMP
、NLS_DATE_FORMAT
などの各国語サポート(NLS)のパラメータによって影響を受けます。
ここでのトピック
関連項目:
言語ソート・パラメータの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。
結合配列に移入した後のNLSパラメータ値の変更
連想配列の文字列索引の格納順序は、初期化パラメータNLS_SORT
およびNLS_COMP
で決まります。
文字列で索引付けされている連想配列にデータを移入した後で、いずれかのパラメータ値を変更すると、コレクション・メソッドFIRST
、LAST
、NEXT
およびPRIOR
から予期しない値が戻されたり例外が呼び出される場合があります。セッション中にこれらのパラメータ値を変更する必要がある場合は、文字列で索引付けされている連想配列に対して操作を実行する前に元の値をリストアしてください。
VARCHAR2以外のデータ型の索引
文字列で索引付けされている連想配列の宣言では、文字列型をVARCHAR2
またはそのサブタイプの1つにする必要があります。
ただし、連想配列への移入では、TO_CHAR
ファンクションでVARCHAR2
に変換できる任意のデータ型の索引を使用できます。
VARCHAR2
およびそのサブタイプ以外のデータ型の索引を使用する場合は、初期化パラメータの値が変更されても索引の一貫性および一意性が保持されることを確認してください。たとえば:
-
TO_CHAR(SYSDATE)
は索引として使用しないでください。NLS_DATE_FORMAT
の値が変更された場合は、(TO_CHAR(SYSDATE))
も変更される可能性があります。 -
それぞれ異なる
NVARCHAR2
の索引でも、同じVARCHAR2
値に変換される可能性のある場合は使用しないでください。 -
大/小文字、アクセント記号またはデリミタ文字のみが異なる
CHAR
またはVARCHAR2
の索引を使用しないでください。NLS_SORT
の値の末尾が_CI
(大/小文字を区別しない比較)または_AI
(アクセント記号の有無および大/小文字を区別しない比較)である場合、大/小文字、アクセント記号またはデリミタ文字のみが異なる索引は同じ値に変換される可能性があります。
リモート・データベースへの結合配列の受渡し
連想配列をパラメータとしてリモート・データベースに渡す場合に、ローカルとリモートのデータベースのNLS_SORT
値またはNLS_COMP
値が異なると、次のようになります。
-
コレクション・メソッド
FIRST
、LAST
、NEXT
またはPRIOR
(「コレクション・メソッド」を参照)から予期しない値が戻されたり例外が呼び出される場合があります。 -
ローカル・データベース上では一意の索引でも、リモート・データベース上では一意でない可能性があり、一意でない場合は事前定義の例外
VALUE_ERROR
が呼び出されます。
結合配列の適切な使用方法
連想配列は、次のような場合に適切です。
-
表が宣言されているサブプログラムの起動またはパッケージの初期化のたびにメモリー内に構成できる比較的小さい参照表
-
データベース・サーバーとの間のコレクションの受渡し
連想配列型の仮サブプログラム・パラメータを宣言します。Oracle Call Interface(OCI)またはOracleプリコンパイラを使用すると、対応する実パラメータにホスト配列がバインドされます。PL/SQLでは、
PLS_INTEGER
で索引付けされているホスト配列と連想配列との間で自動的に変換が行われます。ノート:
VARCHAR
で索引付けされている連想配列はバインドできません。ノート:
スキーマ・レベルでは結合配列型を宣言できません。そのため、連想配列の変数をパラメータとしてスタンドアロン・サブプログラムに渡すには、その変数の型をパッケージ仕様部で宣言する必要があります。このようにすることで、起動されるサブプログラム(結合配列型の仮パラメータを宣言する側)と起動元のサブプログラムまたは無名ブロック(結合配列型の変数を宣言して受け渡す側)の両方で結合配列型を使用できます。例11-2を参照してください。
ヒント:
データベース・サーバーとの間でのコレクションの受渡しには、連想配列を
FORALL
文またはBULK
COLLECT
句とともに使用することが、最も効率的な方法です。詳細は、「FORALL文」および「BULK COLLECT句」を参照してください。
連想配列は、一時的なデータの格納に使用されます。連想配列をデータベース・セッションの期間中持続させるには、パッケージ仕様部で連想配列を宣言し、パッケージ本体で移入します。