e-learning、オラクル研修、LMS(学習管理システム)のiStudy

e-learning、オラクル研修、LMS(学習管理システム)のiStudy

第15回 「結合配列のキーの存在チェック」

2012.04.02

今回は結合配列のキーの存在チェックについて解説します。

結合配列(PL/SQL表、索引付表ともいう)は、新規のキーで代入したときにそのキーの領域がメモリに割り当てられます。
つまり新規のキーで代入することで、お手軽に領域を拡張し値を保持できるのです。
こういったことは同じコレクションでもネストした表とかVARRAYではできないので、結合配列はプログラムで大変使いやすいコレクション変数であるといえます。
(もちろん、ネストした表やVARRAYにも長所はありますが、ここでは触れません)

さて、新規のキーで代入することで領域を拡張するということは、まだ代入していないキーについては存在しないので、存在しないキーでアクセスした場合はエラーとなります。以下がそういった例です。

<<存在しないキーでアクセスしてエラーとなっている例>>
SQL> connect scott/tiger
接続されました。
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2    TYPE  A_TYPE IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
  3    A     A_TYPE;
  4  BEGIN
  5    A(1) := 'ワン';
  6    A(3) := 'スリー';
  7    DBMS_OUTPUT.PUT_LINE(A(2));
  8  END;
  9  /
DECLARE
 
行1でエラーが発生しました。:
ORA-01403: データが見つかりません。
ORA-06512: 行7

ここでは、結合配列Aに対して、キー値 1 とキー値 3 でそれぞれ、'ワン'、'スリー'という値を代入しています。(5-6行目)
したがって、キー値 2 は存在しないのですが、キー値 2 の値を表示する処理(7行目)を行った結果、エラー「ORA-01403: データが見つかりません。」が発生しました。

このキー値を配列の添え字のように考えると、1と3が存在するのだから、あいだの2も存在するように思ってしまいますが、あくまでもキー値なので代入したキー値しか存在しないわけです。

「ORA-01403: データが見つかりません。」というエラーは、SELECT INTO 文が0件の時のエラーと同じなので、NO_DATA_FOUND例外で例外処理できます。
(第6回 SELECT INTO 文の例外処理を参照)
したがって、存在しないキー値を参照したときのエラーも NO_DATA_FOUND例外で処理できます。
以下がそういった例です。

<<存在しないキーのエラーを例外処理している例>>
SQL> DECLARE
  2    TYPE  A_TYPE IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
  3    A     A_TYPE;
  4  BEGIN
  5    A(1) := 'ワン';
  6    A(3) := 'スリー';
  7    DBMS_OUTPUT.PUT_LINE(A(2));
  8  EXCEPTION
  9    WHEN NO_DATA_FOUND THEN
 10          DBMS_OUTPUT.PUT_LINE('存在しないキー値を参照しました');
 11  END;
 12  /
存在しないキー値を参照しました

PL/SQLプロシージャが正常に完了しました。

先ほどの例と違う点は、8-10行を追加した点です。
ここで、NO_DATA_FOUND例外ハンドラにより、存在しないキー値を参照した時のエラーに対して、「存在しないキー値を参照しました」というメッセージを表示して、「正常に完了」させたわけです。
しかしこれでは、エラーが発生したから例外処理をして正常に完了させたに過ぎません。
そういった事後的なエラー対応ではなく、事前にキー値が存在するかどうかをチェックし、その結果によって処理を切り分けていくことが必要になることが多いでしょう。
ではそういったことを意識したプログラミングが以下の例です。

<<キーの存在を事前にチェックしている例>>
SQL> DECLARE
  2    TYPE  A_TYPE IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
  3    A     A_TYPE;
  4  BEGIN
  5    A(1) := 'ワン';
  6    A(3) := 'スリー';
  7    IF A.EXISTS(2) THEN
  8       DBMS_OUTPUT.PUT_LINE(A(2));
  9    ELSE
 10       DBMS_OUTPUT.PUT_LINE('キー値 2 は存在しません');
 11    END IF;
 12  END;
 13  /
キー値 2 は存在しません

PL/SQLプロシージャが正常に完了しました。

ここで、ポイントは7行目の記述です。
A.EXISTS(2) という記述は結合配列Aにキー値2が存在していればTRUEを返し、存在していなければ、FALSEを返すので、結果として今回は、ELSE以下の10行目のコードが実行され、「キー値 2 は存在しません」とういメッセージを表示しています。
このような機能をもちいれば、結合配列を参照する前に、そのキー値の存在チェックができるので、存在しないキー値で参照するエラーを防ぐことができます。
なお、この「EXISTS」は結合配列のメソッドの一つです。

キー値の値として、プログラムの中で添え字のように1,2,3・・と連続した番号で代入しているような場合は、存在しないキー値で参照することは考えにくいでしょう。しかしキーの値に連続しない値を用いることも可能ですし、またパッケージ(注1)に結合配列を格納しておけば、セッションが終るまでは同一セッションでその変数を保持します。そういった場合は、どのようなキー値が使われているか後続のプログラムからは判断できないこともありますので、キー値の存在確認が必要なケースもあり、EXISTSメソッドは大いに役に立ちます。
(注1 パッケージについては別の機会に詳しく説明する予定です)

それでは、今回はここまでとします。また、次回ご期待ください。

先頭へ戻る