例外処理(エラー処理) (Oracle編)


ITコーディネータのシュウです。

DSC_2080_2

前回に引き続き、加須花崎水上公園で撮った写真です。用水路に鳥が泳いでいました。おそらくカルガモだと思います。スイスイーと気持ちよさそうに泳いでました。たまに行列を作って行進したりする姿も見かけますよね。

そういえば、「鴨の水搔き」という言葉がありますが、《気楽そうに浮かんでいる鴨も、水面下では水かきを絶えず動かしているところから》人知れない苦労があることのたとえで使われる言葉なんですよね。
見習うところも多いかもしれませんね。

<本日の題材>
例外処理(エラー処理) (Oracle編)

今回は、処理の途中で例外(エラー)が発生した場合の処理を記述する例外処理(エラー処理)について取り上げてみたいと思います。ORACLEのPL/SQL とSQL ServerのTransact SQLでは記述の仕方が異なるため、今回はまずORACLEについて見てみたいと思います。

PL/SQLでは、実行時のエラーや警告のことを例外と言いますが、もし、処理の途中で例外が発生したときに、PL/SQLブロックに実行部しかなかった場合、PL/SQLは異常終了(OS側に制御が戻る)します。

例えば、ある商品について、前年の出荷実績に対する今年の予算の比率を計算で出す処理をPL/SQLで記述した場合、新商品のためなどの理由で前年の出荷実績が 0 であった場合には、下記のようになります。

DECLARE
  Yosan  NUMBER := 12000;
  Zennen_Jisseki  NUMBER := 0;
  Tai_Zennenhi NUMBER;
BEGIN
  Tai_Zennenhi := 100.0 * Yosan / Zennen_Jisseki;
  DBMS_OUTPUT.PUT_LINE('予算/前年実績 = ' || Tai_Zennenhi||'%');
END;
/

上記を実行すると(SQL Plus)、下記のような ORA-01476 のエラーが出て異常終了します。これは数値を0で割ろうとしたときに出るエラーです。
plsql_err

これについて、下記のように例外処理部を追加してエラーのときの対応を明記することで、異常終了させずに正常終了させることができます。例外処理部は、BEGIN ~ END; の間に、EXCEPTION句を入れて、EXCEPTION ~ END; の間に例外処理を記述します。

DECLARE
  Yosan  NUMBER := 12000;
  Zennen_Jisseki  NUMBER := 0;
  Tai_Zennenhi NUMBER;
BEGIN
  Tai_Zennenhi := 100.0 * Yosan / Zennen_Jisseki;
  DBMS_OUTPUT.PUT_LINE('予算/前年実績 = ' || Tai_Zennenhi||'%');
EXCEPTION
  WHEN ZERO_DIVIDE THEN
      DBMS_OUTPUT.PUT_LINE('0で数値を割ろうとしています');
      Tai_Zennenhi := NULL; 
  WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('他のエラーが発生しました');
      Tai_Zennenhi := NULL;
END;
/
plsql_例外処理JPG

上記は、予算を前年実績の0値で割ろうとしたときに、「ZERO_DIVIDE」という例外が発生し、EXCEPTION以下の例外処理部に処理が移り、「0で数値を割ろうとしています」というメッセージを出して処理を終了しています。

例外が発生したときの制御は以下のようになります。

plsql_例外処理制御

 ただ、上記のように 0 で割る可能性があらかじめわかっている場合は、処理1のところにエラーチェックを行うことで例外を回避できます。

DECLARE
  Yosan  NUMBER := 12000;
  Zennen_Jisseki  NUMBER := 0;
  Tai_Zennenhi NUMBER;
BEGIN
  Tai_Zennenhi := CASE Zennen_Jisseki WHEN 0 THEN NULL
                                             ELSE 100.0 * Yosan / Zennen_Jisseki END;

  IF Tai_Zennenhi IS NOT NULL THEN
    DBMS_OUTPUT.PUT_LINE('予算/前年実績 = ' || Tai_Zennenhi||'%');
  ELSE
    DBMS_OUTPUT.PUT_LINE('前年実績はありませんでした');
  END IF;
 
EXCEPTION
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('他のエラーが発生しました');
      Tai_Zennenhi := NULL;
END;
/

plsql_例外処理回避

 この場合、予算の対前年実績比率を出す際に、CASE文で 0 で割るのではなく NULLに設定するかたちにしており、例外処理は発生していません。

今日は以上まで

にほんブログ村 IT技術ブログへ
にほんブログ村

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>