例外のトラップ

この項では、事前定義のTimesTenエラーまたはユーザー定義のエラーをトラップする方法について説明します。

事前定義済TimesTenエラーのトラップ

事前定義のTimesTenエラーをトラップするには、例外処理ルーチンで事前定義の名前を参照します。PL/SQLでは、STANDARDパッケージで事前定義例外が宣言されています。

詳細は、次を参照してください。

事前定義済例外のリファレンス

TimesTenでサポートされている事前定義済の例外を示します。

表4-1に、例外について、関連するORAエラー番号とSQLCODE値、および説明を示します。

「サポートされていない事前定義済エラー」も参照してください。

表4-1 事前定義済例外

例外名 Oracle Databaseエラー番号 SQLCODE 説明

ACCESS_INTO_NULL

ORA-06530

-6530

初期化されていないオブジェクトの属性に値を割り当てようとしました。

CASE_NOT_FOUND

ORA-06592

-6592

CASE文のWHEN句で何も選択されておらず、ELSE句もありません。

COLLECTION_IS_NULL

ORA-06531

-6531

EXISTS以外のコレクション・メソッドを初期化されていないネストした表やVARRAYに適用しようとしたか、または初期化されていないネストした表やVARRAYの要素に値を割り当てようとしました。

CURSOR_ALREADY_OPENED

ORA-06511

-6511

すでにオープンされているカーソルをオープンしようとしました。

DUP_VAL_ON_INDEX

ORA-00001

-1

プログラムは一意索引によって制約されている列に重複値を挿入しようとしました。

INVALID_CURSOR

ORA-01001

-1001

無効なカーソル操作があります。

INVALID_NUMBER

ORA-01722

-1722

文字列から数値への変換に失敗しました。

NO_DATA_FOUND

ORA-01403

+100

単一行のSELECTによって行が戻されなかったか、またはプログラムによって、ネストした表内の削除された要素や連想配列(索引付き表)内の初期化されていない要素が参照されました。

PROGRAM_ERROR

ORA-06501

-6501

PL/SQLに内部的な問題が発生しました。

ROWTYPE_MISMATCH

ORA-06504

-6504

代入文のホスト・カーソル変数とPL/SQLカーソル変数の戻り型に互換性がありません。

STORAGE_ERROR

ORA-06500

-6500

PL/SQLのメモリーが不足しているか、メモリーが破損しています。

SUBSCRIPT_BEYOND_COUNT

ORA-06533

-6533

コレクション内の要素の数より大きい索引番号を使用して、ネストした表またはVARRAYを参照しました。

SUBSCRIPT_OUTSIDE_LIMIT

ORA-06532

-6532

有効範囲外の索引番号(たとえば-1)を使用して、ネストした表またはVARRAY要素を参照しました。

SYS_INVALID_ROWID

ORA-01410

-1410

文字列がROWID値を表していないため、ユニバーサルROWIDへの文字列の変換に失敗しました。

TOO_MANY_ROWS

ORA-01422

-1422

単一行SELECTが複数の行を戻しました。

VALUE_ERROR

ORA-06502

-6502

算術、変換、切捨てまたはサイズ制限のエラーが発生しました。

ZERO_DIVIDE

ORA-01476

-1476

数値を0(ゼロ)で割ろうとしました。

事前定義済例外の例

この例のPL/SQLプログラムでは、数値を0で割ろうとします。事前定義例外ZERO_DIVIDEを使用して、例外処理ルーチン内でエラーをトラップします。

Command> DECLARE v_invalid PLS_INTEGER;
         BEGIN
           v_invalid := 100/0;
         EXCEPTION
         WHEN ZERO_DIVIDE THEN
           DBMS_OUTPUT.PUT_LINE ('Attempt to divide by 0');
         END;
         /
Attempt to divide by 0
 
PL/SQL procedure successfully completed.

ユーザー定義例外のトラップ

TimesTenのPL/SQLでは、ユーザー独自の例外を定義することができ、またPL/SQL RAISE文またはRAISE_APPLICATION_ERRORプロシージャで明示的にユーザー定義の例外を発生させることができます。

これらのプロセスについては、次の項で説明します。

RAISE文の使用方法

RAISE文を使用すると、PL/SQLブロックまたはサブプログラムの実行を停止し、制御を例外ハンドラに渡すことができます。RAISE文では、事前定義例外または自分で名前を付けたユーザー定義例外を呼び出すことができます。

次の例では、部門番号500は存在しないため、departments表内の行は更新されません。RAISE文を使用して例外を明示的に呼び出し、SQLERRM組込みファンクションによって戻されるエラー・メッセージとSQLCODE組込みファンクションによって戻されるエラー・コードを表示します。例外ハンドラ内で、RAISE文を単独で使用して同じ例外を再度呼び出し、コール元の環境に伝播します。

Command> DECLARE
           v_deptno NUMBER := 500;
           v_name VARCHAR2 (20) := 'Testing';
           e_invalid_dept EXCEPTION;
          BEGIN
           UPDATE departments
           SET department_name = v_name
           WHERE department_id = v_deptno;
          IF SQL%NOTFOUND THEN
             RAISE e_invalid_dept;
          END IF;
          ROLLBACK;
          EXCEPTION
            WHEN e_invalid_dept THEN
            DBMS_OUTPUT.PUT_LINE ('No such department');
            DBMS_OUTPUT.PUT_LINE (SQLERRM);
            DBMS_OUTPUT.PUT_LINE (SQLCODE);
         END;
         /
No such department
User-Defined Exception
1
 
PL/SQL procedure successfully completed.
 
The command succeeded.

ノート:

TimesTenとOracle Databaseでエラー条件が同じ場合、SQLCODEによって戻されるエラー・コードは同じですが、SQLERRMによって戻されるエラー・メッセージは同じとはかぎりません。これについては、「TimesTenのエラー・メッセージおよびSQLコード」でも説明しています。

RAISE_APPLICATION_ERRORプロシージャの使用

RAISE_APPLICATION_ERRORプロシージャは、PL/SQLプログラムの実行可能セクションまたは例外セクション(あるいはその両方)で使用します。TimesTenによってアプリケーションにエラーがレポートされるため、未処理例外を戻すのを回避できます。

-20,000から-20,999の範囲のエラー番号を使用します。メッセージには最大2,048バイトの文字列を指定します。

次の例では、employees表からlast_name=Pattersonのデータを削除しようとします。RAISE_APPLICATION_ERRORプロシージャで、エラー番号-20201を使用してエラーを呼び出します。

Command> DECLARE
           v_last_name employees.last_name%TYPE := 'Patterson';
         BEGIN
         DELETE FROM employees WHERE last_name = v_last_name;
         IF SQL%NOTFOUND THEN
           RAISE_APPLICATION_ERROR (-20201, v_last_name || ' does not exist');
         END IF;
         END;
         /
 8507: ORA-20201: Patterson does not exist
 8507: ORA-06512: at line 6
The command failed.