ITコーディネータのシュウです。
娘がディズニーランドに行ってきて、撮ってきた写真です。
昨年、社会現象にもなったアナと雪の女王をテーマにした、スペシャルイベント「アナとエルサのフローズンファンタジー」。入口のところで大きく宣伝してたのを帰る時に撮ったと言ってました。シンデレラ城を舞台にしたプロジェクションマッピング「ワンス・アポン・ア・タイム~スペシャルウィンターエディション」は座席指定券をもらう抽選に当たらなかったので、いい席では見れなかったと残念がってました。
4月からチケットが少し値上がりしてしまうのは残念だけど、それでも何度でも行ってみたくなる魅力がありますよね!
さて、話は変わりますが、dbSheetClientのユーザー事例に紀文食品様が載りました。おでん用の商品などに「紀文」の焼印が押されていることでも有名な、練り製品ではトップシェアを持つ会社ですね。
dbSheetClientで念願の「品質検査管理システム」を構築したとのこと。詳しくは、こちらを参照してみてください。
http://www.newcom07.jp/dbsheetclient/usrvoice/usrcase8.html
<本日の題材>
例外処理(エラー処理) (Oracle編2)
前回は、ORACLEの例外処理についての一般的記述方法や制御について取り上げてみました。今回は、ORACLEの例外の種類とそれに応じた記述方法について、見てみます。
例外は内部例外とユーザー定義例外にわけられ、内部例外はさらに事前定義の内部例外と無名の内部例外に分けられます。
事前定義の内部例外には、前回の例で示した
・数値データをゼロで割ろうとした「ZERO_DIVIDE」例外(ORA-01476)
・SELECT INTO文で複数の行を戻したときの「TOO_MANY_ROWS」例外(ORA-01422)
・検索の結果1行も戻されない「NO_DATA_FOUND」例外(ORA-01403)
などいろいろあります。
こういったものは、それぞれに名前が定義されているため、例外処理部で個別に処理を指定することができますが、名前が付けられていない無名の内部例外については、宣言部で明示的に名前を付けてあげ、さらに PRAGMA EXCEPTION_INITでORACLEのエラーと例外名を関連付ける必要があります。
例)
DECLARE
KETA_ERR EXCEPTION;
PRAGMA EXCEPTION_INIT(KETA_ERR, -01438);
BEGIN
INSERT INTO DEPT(DEPTNO, DNAME) VALUES(501, '企画部');
COMMIT;
EXCEPTION
WHEN KETA_ERR THEN
DBMS_OUTPUT.PUT_LINE('桁数が大きすぎます');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(sqlcode);
DBMS_OUTPUT.PUT_LINE(sqlerrm);
END;
/
これは、DEPT表にデータを登録する際、DEPTNOは2桁の数値でなければならないところ、3桁を登録しようとしたときに出る無名の内部例外、「ORA-01438:この列に許容される指定精度より大きな値です」に名前を付けて、それを例外処理部で使っている例です。
なお、OTHERSハンドラを使用すると、例外処理部で例外名が指定されていないすべての例外を処理することができるため、上記の例では「KETA_ERR」例外以外の例外が発生した場合には、OTHERSハンドラの処理が行われるようになります。
そのときにどのような例外が発生したのかを確認するのに、SQLCODE関数(エラー番号を戻す関数)、SQLERRM関数(エラーメッセージを戻す関数)のようなエラー報告関数をすると便利です。
さて、ユーザー定義例外というのは、ORACLEのエラーではなく、ユーザーが作成する例外になります。
下の例は、FOR LOOP文の繰り返しの中で、ある数量をマイナスしていき、その数値が10未満になった場合には、ユーザー定義例外を呼出して、エラーとして処理するというものです。
例)
DECLARE
Amount NUMBER;
Amount_ERR EXCEPTION; -- ユーザー定義例外の宣言
BEGIN
Amount := 20;
FOR lc IN 1..30 LOOP
Amount := Amount – 1;
IF Amount < 10 THEN
RAISE Amount_ERR; -- ユーザー定義例外の呼出し
END IF;
END LOOP;
EXCEPTION
WHEN Amount_ERR THEN
DBMS_OUTPUT.PUT_LINE(‘ユーザー定義例外発生: 数量 = ‘||Amount);
END;
/
また、ユーザーが独自に「ORA-xxxx」形式のエラーコードとエラーメッセージを定義して、エラーを表示させるような場合には、RAISE_APPLICATION_ERROR を使用します。
このときにユーザー定義のエラーとして使用が許可されている番号は ORA-20000~ORA-20999 までです。
例)
RAISE_APPLICATION_ERROR(-20001, 'エラーが発生しました');
また、例外が発生して処理が例外処理部に移ると、制御は実行部には戻らないため、処理の途中でブロックは終了してしまいます。しかし、その後も処理を継続したい場合には、ブロックのネストを使用することで可能になります。
例)
DECLARE
Amount NUMBER;
Amount_ERR EXCEPTION;
BEGIN
Amount := 20;
FOR lc IN 1..10 LOOP
BEGIN -- ブロックのネスト
Amount := Amount - 2;
IF Amount = 10 THEN
RAISE Amount_ERR;
ELSE
DBMS_OUTPUT.PUT_LINE('Amount = '||Amount);
END IF;
EXCEPTION -- ネストされたブロック内での例外処理
WHEN Amount_ERR THEN
DBMS_OUTPUT.PUT_LINE('ユーザー定義例外発生:数量 = '||Amount);
END;
END LOOP;
END;
/
上記は、Amountの値が10になった時点で例外が発生していますが、ネストされたブロックの中での例外のため、その後のLOOPの処理が継続されていることが確認できます。
今日は以上まで
にほんブログ村