5-3. その他の例外処理(RAISE_APPLICATION_ERROR)

続いて、RAISE_APPLICATION_ERRORプロシージャを使用する方法です。

この方法は、任意の例外のエラーコードを指定することができますが、使用可能なエラーコードは-20000から-20999までの1000個と制限されています。
かつ、サードパーティー製のプロダクトと併用するようなケースでは、この番号が既に使用されている場合もあり、開発済みのプログラムで使用しているエラーコードとバッティングしてしまう可能性もあります。

その際も、エラーメッセージはテーブル等のメッセージディクショナリで管理し、エラーコードからメッセージ文言を取得すべきですし、できれば引数を与えて文字列の置換を行えるようにした方が良いでしょう。
用途にもよりますが、複数言語対応も行えると良いでしょう。
このような機能を実現する共通機能をあらかじめ提供できるのが望ましいです。

RAISE_APPLICATION_ERRORの使用方法

 事前にエラーコードのみを定義しておき、RAISE_APPLICATION_ERRORでエラーコードを指定します。
 RAISE_APPLICATION_ERROR実行時にメッセージも指定できます。

CREATE OR REPLACE PACKAGE BODY expt_sample
IS
  cn_err_code_sal_over_range CONSTANT NUMBER(6) := -20002;
--
  CURSOR c_emp(iv_dept IN VARCHAR2)
  IS
  SELECT e.empno, e.ename, e.deptno, d.dname, e.sal*100 AS sal, e.comm
  FROM   emp e INNER JOIN dept d ON (e.deptno = d.deptno)
  WHERE  e.deptno = iv_dept;
--
  PROCEDURE ins(ir_emp IN c_emp%ROWTYPE)
  IS
    cv_proc_name CONSTANT VARCHAR2(30) := 'ins';
  BEGIN
    -- salの値チェック
    IF ir_emp.sal > 1000 THEN
      -- ユーザー定義例外の呼出
      RAISE_APPLICATION_ERROR(cn_err_code_sal_over_range, 'salの値が大きすぎます。');
--      RAISE expt_sal_over_range;
    END IF;
    INSERT INTO emp_sample
    VALUES(ir_emp.empno, ir_emp.ename, ir_emp.deptno, ir_emp.dname, ir_emp.sal, ir_emp.comm);
  EXCEPTION
    WHEN OTHERS THEN
      -- RAISE_APPLICATION_ERRORもここでハンドリング
      dbms_output.put_line(cv_proc_name || ' : ' || SQLERRM);
      RAISE;
  END ins;
--
  PROCEDURE sel(iv_dept IN VARCHAR2)
  IS
    cv_proc_name CONSTANT VARCHAR2(30) := 'sel';
    r_emp c_emp%ROWTYPE;
  BEGIN
    FOR r_emp IN c_emp(iv_dept)
    LOOP
      ins(r_emp);
    END LOOP;
  EXCEPTION
    WHEN OTHERS THEN
      dbms_output.put_line(cv_proc_name || ' : ' || SQLERRM);
      RAISE;
  END sel;
--
  PROCEDURE main(iv_dept IN VARCHAR2)
  IS
    cv_proc_name CONSTANT VARCHAR2(30) := 'main';
  BEGIN
    sel(iv_dept);
  EXCEPTION
    WHEN OTHERS THEN
      dbms_output.put_line(cv_proc_name || ' : ' || SQLERRM);
      RAISE;
  END main;
END expt_sample;
/

実行結果(※メッセージは定義していないので出力されない)


ins : ORA-20002: salの値が大きすぎます。
sel : ORA-20002: salの値が大きすぎます。
main : ORA-20002: salの値が大きすぎます。

Posted by tfurukaw