での例外処理 Oracle PL/SQL (例)
⚡ スマートサマリー
例外処理 Oracle PL/SQLは、ブロックの実行を妨げる実行時エラーを捕捉し、エンジンが制御をEXCEPTIONセクションに渡せるようにします。EXCEPTIONセクションでは、事前定義済み、ユーザー定義、およびその他のハンドラがエラーに安全に応答、発生、または伝播します。

PL/SQL の例外処理とは何ですか?
An exception occurs when the PL/SQL engine encounters an instruction it cannot execute because of an error that arises at run-time. These errors are not detected at compile time and therefore must be handled only at run-time.
例えば、PL/SQLエンジンが数値をゼロで割る命令を受け取った場合、エラーを例外として発生させます。この例外は、PL/SQLエンジンによって実行時にのみ発生します。
例外が発生するとプログラムの実行が停止するため、このような事態を避けるためには、エラーを捕捉して個別に処理する必要があります。このプロセスは例外処理と呼ばれ、プログラマーは実行時に発生する可能性のあるエラーを処理します。
例外処理構文
Exceptions are handled at the block level. Once an exception occurs in a block, control leaves the execution part of that block, and the exception is then handled in the exception-handling part of the block. After the exception is handled, control cannot return to the execution section of that same block.
以下の図は、実行セクションと例外処理セクションが単一のPL/SQLブロック内にどのように配置されているかを示しています。
以下の構文は、例外を捕捉して処理する方法を示しています。
BEGIN <execution block> . . EXCEPTION WHEN <exceptionl_name> THEN <Exception handling code for the “exception 1 _name’' > WHEN OTHERS THEN <Default exception handling code for all exceptions > END;
構文の説明:
- 上記の構文では、例外処理ブロックには、例外を処理するための一連のWHEN条件が含まれています。
- 各WHEN条件の後には、実行時に発生することが想定される例外名が続きます。
- When an exception is raised at run-time, the PL/SQL engine searches the exception-handling part for that particular exception, starting from the first WHEN clause and moving sequentially.
- If it finds a handler for the exception that was raised, it executes that particular handler code.
- 発生した例外に一致するWHEN句がない場合、PL/SQLエンジンはWHEN OTHERS部分が存在する場合はそれを実行します。このハンドラはすべての例外に共通です。
- ハンドラの実行後、制御は現在のブロックから離れます。
- 実行時にブロックに対して実行できる例外ハンドラは1つだけです。例外ハンドラの実行が完了すると、エンジンは残りのハンドラをスキップし、現在のブロックを終了します。
注意: WHEN OTHERS は常にシーケンスの最後に配置する必要があります。WHEN OTHERS の実行が完了するとブロックから制御が抜けるため、WHEN OTHERS の後に記述されたハンドラは決して実行されません。
例外の種類
There are two types of exceptions in PL / SQLの.
- 定義済みの例外
- ユーザー定義の例外
事前定義された例外
Oracle には、いくつかの一般的な例外が定義されています。定義済みの例外にはそれぞれ一意の名前とエラー番号があり、それらはすべて STANDARD パッケージで宣言されています。 Oracle. In code, you can use these predefined exception names directly to handle the corresponding errors. Many of them map directly to common SQL 日常的に遭遇するエラー。
Below are a few predefined exceptions:
| 例外 | エラー Code | 例外の理由 |
|---|---|---|
| ACCESS_INTO_NULL | ORA-06530 | 初期化されていないオブジェクトの属性に値を割り当てる |
| CASE_NOT_FOUND | ORA-06592 | CASE文のWHEN句はどれも満たされておらず、ELSE句も指定されていません。 |
| COLLECTION_IS_NULL | ORA-06531 | 初期化されていないコレクションに対してコレクションメソッド(EXISTSを除く)を使用したり、コレクション属性にアクセスしたりすること |
| CURSOR_ALREADY_OPEN | ORA-06511 | を開こうとしています カーソル すでにオープンしている |
| DUP_VAL_ON_INDEX | ORA-00001 | 一意インデックスによって制約されているデータベース列に重複値を格納する |
| INVALID_CURSOR | ORA-01001 | 開いていないカーソルを閉じるなど、不正なカーソル操作 |
| 無効な番号 | ORA-01722 | 無効な数値文字のため、文字を数値に変換できませんでした。 |
| 何もデータが見つかりませんでした | ORA-01403 | A SELECT statement that contains an INTO clause fetches no rows |
| ROW_MISMATCH | ORA-06504 | カーソル変数のデータ型は、実際のカーソル戻り値の型と互換性がありません。 |
| SUBSCRIPT_BEYOND_COUNT | ORA-06533 | コレクションのサイズよりも大きいインデックス番号でコレクションを参照する |
| SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | 法定範囲外のインデックス番号(例:-1)でコレクションを参照すること |
| TOO_MANY_ROWS | ORA-01422 | INTO句を含むSELECT文は、複数の行を返します。 |
| VALUE_ERROR | ORA-06502 | 計算エラーまたはサイズ制約エラー(例えば、変数のサイズよりも大きい値を代入した場合など) |
| ZERO_DIVIDE | ORA-01476 | 数をゼロで割る |
ユーザー定義の例外
上記の定義済み例外に加えて、プログラマはカスタム例外を作成して処理することもできます。カスタム例外はサブルーチンレベルの宣言部分で作成され、そのサブルーチン内でのみ有効です。パッケージ仕様で定義された例外はパブリック例外であり、パッケージにアクセスできる場所であればどこからでも有効です。
Syntax: At subprogram level
DECLARE <exception_name> EXCEPTION; BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> END;
- 上記の構文では、変数「exception_name」はEXCEPTION型として定義されています。
- It can then be used in the same way as a predefined exception.
構文: パッケージ仕様レベルで
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- 上記の構文では、変数「exception_name」はパッケージ仕様のEXCEPTION型として定義されています。 。
- パッケージ「package_name」が呼び出されるデータベース内のあらゆる場所で使用できます。
PL/SQLによる例外の発生
定義済みの例外は、対応するエラーが発生すると自動的に発生します。ただし、ユーザー定義の例外は、キーワードRAISEを使用して明示的に発生させる必要があります。RAISEは、以下に示す方法で使用できます。
ハンドラ内で RAISE を単独で使用すると、既に発生した例外が親ブロックに伝播されます。RAISE は、以下に示すように、例外ブロック内でのみ使用できます。
以下のスクリーンショットは、RAISE を単独で使用して、囲んでいるブロックに対して例外を再発生させた例を示しています。
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
構文の説明:
- 上記の構文では、キーワードRAISEが例外処理ブロック内で使用されています。
- プログラムが例外「exception_name」に遭遇した場合、例外は処理され、正常に完了します。
- The keyword RAISE in the handler then propagates that same exception to the parent program.
注意: 親ブロックに例外を発生させる場合、発生する例外は親ブロック内でも可視である必要があります。そうでない場合 Oracle エラーがスローされます。
You can also use the keyword RAISE followed by an exception name to raise that particular user-defined or predefined exception. This form can be used in both the execution part and the exception-handling part.
以下のスクリーンショットは、RAISEコマンドに例外名を続けて指定することで、特定の例外を発生させる例を示しています。
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
構文の説明:
- 上記の構文では、実行部分でキーワードRAISEが使用され、その後に例外「exception_name」が続きます。
- This raises that particular exception at run-time, and it then needs to be handled or raised further.
例1: この例では、次のことがわかります。
- 例外を宣言する方法
- 宣言された例外を発生させる方法
- メインブロックへの伝播方法
以下のスクリーンショットは、sample_exceptionを宣言し、ネストされたブロック内でそれを発生させ、メインブロックに伝播させる完全なブロックを示しています。
次のスクリーンショットは、同じ例の続きを示しており、メインブロックが最終的に伝播された例外を捕捉している様子が分かります。
DECLARE Sample_exception EXCEPTION; PROCEDURE nested_block IS BEGIN Dbms_output.put_line('Inside nested block'); Dbms_output.put_line('Raising sample_exception from nested block'); RAISE sample_exception; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line ('Exception captured in nested block. Raising to main block'); RAISE; END; BEGIN Dbms_output.put_line('Inside main block'); Dbms_output.put_line('Calling nested block'); Nested_block; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line ('Exception captured in main block'); END; /
Code 説明:
- Code 2行目: 変数「sample_exception」をEXCEPTION型として宣言します。
- Code 3行目: Declaring the procedure nested_block.
- Code 6行目: 「ネストされたブロック内」という文を出力します。
- Code 7行目: 「ネストされたブロックから sample_exception を発生させています」というステートメントを出力します。
- Code 8行目: 「RAISEサンプル例外」を使用して例外を発生させます。
- Code 10行目: Exception handler for the exception sample_exception in the nested block.
- Code 11行目: 「ネストされたブロックで例外が捕捉されました。メインブロックに移行します」というステートメントを出力します。
- Code 12行目: 例外をメインブロックに伝播させる。
- Code 15行目: 「メインブロック内」という文を印刷します。
- Code 16行目: 「ネストされたブロックの呼び出し」ステートメントを出力します。
- Code 17行目: nested_blockプロシージャを呼び出しています。
- Code 19行目: メインブロックのsample_Exceptionの例外ハンドラ。
- Code 20行目: 「メインブロックで例外が捕捉されました」という文を出力します。
例外の注意点
- 関数内では、例外は常に値を返すか、例外をさらに発生させる必要があります。 Oracle 実行時に「関数が値なしで返されました」というエラーが発生します。
- 取引管理ステートメント 例外処理ブロック内で発行できます。
- SQLERRMとSQLCODEは、それぞれ例外メッセージと例外コードを返す組み込み関数です。
- 例外が処理されない場合、デフォルトではそのセッション内のすべてのアクティブなトランザクションがロールバックされます。
- RAISE_APPLICATION_ERROR (- 、 RAISE の代わりに を使用すると、カスタムコードとメッセージでエラーを発生させることができます。エラーコードは -20000 ~ -20999 の範囲である必要があります。





