Oracle PL/SQL での例外処理 (例)

PL/SQL の例外処理とは何ですか?

実行時に発生するエラーにより、PL/SQL エンジンが実行できない命令を検出すると、例外が発生します。 これらのエラーはコンパイル時には捕捉されないため、実行時にのみ処理する必要があります。

たとえば、PL/SQL エンジンが任意の数値を「0」で除算する命令を受け取ると、PL/SQL エンジンはそれを例外としてスローします。 例外は、PL/SQL エンジンによって実行時にのみ発生します。

例外によりプログラムの実行が停止されるため、そのような状態を回避するには、例外を個別に取得して処理する必要があります。 このプロセスは例外処理と呼ばれ、プログラマは実行時に発生する可能性のある例外を処理します。

例外処理構文

例外はブロック レベルで処理されます。つまり、いずれかのブロックで例外が発生すると、制御はそのブロックの実行部分から出ます。 例外は、そのブロックの例外処理部分で処理されます。 例外を処理した後は、そのブロックの実行セクションに制御を再送信することはできません。

以下の構文は、例外をキャッチして処理する方法を説明しています。

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 条件の後には、実行時に発生すると予想される例外名が続きます。
  • 実行時に例外が発生すると、PL/SQL エンジンは例外処理部分でその特定の例外を調べます。 最初の WHEN 句から開始して、順番に検索します。
  • 発生した例外に対する例外処理が見つかった場合は、その特定の処理コード部分が実行されます。
  • 発生した例外に対して「WHEN」句が存在しない場合、PL/SQLエンジンは「WHEN OTHERS」部分(存在する場合)を実行します。 これはすべての例外に共通です。
  • 例外の実行後、パート制御は現在のブロックの外に出ます。
  • 実行時にブロックに対して実行できる例外部分は XNUMX つだけです。 実行後、コントローラーは残りの例外処理部分をスキップし、現在のブロックから抜け出します。

注: WHEN OTHERS は常にシーケンスの最後の位置になければなりません。 WHEN OTHERS の実行後にコントロールがブロックから抜けるため、WHEN OTHERS の後に存在する例外処理部分は決して実行されません。

例外の種類

例外には XNUMX 種類あります PL/SQL.

  1. 事前定義された例外
  2. ユーザー定義の例外

事前定義された例外

Oracle では、いくつかの一般的な例外が事前定義されています。 これらの例外には、一意の例外名とエラー番号があります。 これらの例外は、Oracle の「STANDARD」パッケージですでに定義されています。 コードでは、これらの事前定義された例外名を直接使用して、それらを処理できます。

以下にいくつかの事前定義された例外を示します。

例外 エラーコード 例外の理由
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 INTO 句を含む 'SELECT' ステートメントが行をフェッチしない場合。
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 数値を「0」で割る

ユーザー定義の例外

Oracle では、上記の事前定義された例外以外に、プログラマが独自の例外を作成して処理することができます。 これらは、宣言部分のサブプログラム レベルで作成できます。 これらの例外は、そのサブプログラム内でのみ表示されます。 パッケージ仕様で定義されている例外はパブリック例外であり、パッケージにアクセスできる場所であればどこでも表示されます。

構文: サブプログラムレベルで

DECLARE
<exception_name> EXCEPTION; 
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN 
<Handler>
END;
  • 上記の構文では、変数「例外名」は「EXCEPTION」タイプとして定義されています。
  • これは、事前定義された例外と同様の方法で使用できます。

構文:パッケージ仕様レベルで

CREATE PACKAGE <package_name>
 IS
<exception_name> EXCEPTION;
.
.
END <package_name>;
  • 上記の構文では、変数「例外名」は、パッケージ仕様の「EXCEPTION」タイプとして定義されています。 。
  • これは、パッケージ「package_name」を呼び出すことができるデータベースのどこでも使用できます。

PL/SQLによる例外の発生

エラーが発生するたびに、すべての事前定義例外が暗黙的に発生します。 ただし、ユーザー定義の例外は明示的に発生させる必要があります。 これはキーワード「RAISE」を使用して実現できます。 これは、以下で説明するいずれかの方法で使用できます。

'RAISE' がプログラム内で個別に使用される場合、すでに発生した例外が親ブロックに伝播されます。 以下のように例外ブロック内でのみ使用できます。

PL/SQLによる例外の発生

CREATE [ PROCEDURE | FUNCTION ]
 AS
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN 
             <Handler>
RAISE;
END;

構文の説明:

  • 上記の構文では、キーワード RAISE が例外処理ブロックで使用されています。
  • プログラムが例外「例外名」に遭遇すると、例外は処理され、正常に完了します。
  • ただし、例外処理部分のキーワード「RAISE」は、この特定の例外を親プログラムに伝播します。

注: 親ブロックに対して例外を発生させる際、発生している例外は親ブロックでも表示される必要があります。そうでない場合、Oracle はエラーをスローします。

  • キーワード「RAISE」の後に例外名を指定すると、特定のユーザー定義/定義済み例外を発生させることができます。 これは、実行部分と例外処理部分の両方で例外を発生させるために使用できます。

PL/SQLによる例外の発生

CREATE [ PROCEDURE | FUNCTION ] 
AS
BEGIN
<Execution block>
RAISE <exception_name>
EXCEPTION
WHEN <exception_name> THEN
<Handler>
END;

構文の説明:

  • 上記の構文では、キーワード RAISE が実行部分で使用され、その後に例外「例外名」が続きます。
  • これにより、実行時にこの特定の例外が発生するため、これを処理するか、さらに発生させる必要があります。

: この例では、次のことを確認します。

  • 例外を宣言する方法
  • 宣言された例外を発生させる方法と
  • メインブロックへの伝播方法

PL/SQLによる例外の発生

PL/SQLによる例外の発生

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:
/

コードの説明:

  • コード行 2: 変数「sample_Exception」を EXCEPTION 型として宣言します。
  • コード行 3: プロシージャnested_blockを宣言しています。
  • コード行 6: ステートメント「ネストされたブロックの内側」を出力します。
  • コード行 7: 「ネストされたブロックからのsample_Exceptionの発生」ステートメントを出力します。
  • コード行 8: 「RAISEサンプル例外」を使用して例外を発生させます。
  • コード行 10: ネストされたブロック内の例外サンプル例外の例外ハンドラー。
  • コード行 11: ステートメント「ネストされたブロックで例外がキャプチャされました。」を出力します。 メインブロックまで上げます。
  • コード行 12: メイン ブロックに例外を発生させます (メイン ブロックに伝播します)。
  • コード行 15: 「メインブロックの内側」というステートメントを印刷します。
  • コード行 16: 「ネストされたブロックの呼び出し」ステートメントを出力します。
  • コード行 17: nested_block プロシージャを呼び出します。
  • コード行 18: 例外
  • コード行 19: メインブロックのsample_Exceptionの例外ハンドラ。
  • コード行 20: 「メインブロックで例外が捕捉されました。」というステートメントを出力します。

例外の注意点

  • 関数では、例外は常に値を返すか、さらに例外を発生させる必要があります。 そうしないと、Oracle は実行時に「関数が値なしで返されました」エラーをスローします。
  • トランザクション制御ステートメントは、例外処理ブロックで指定できます。
  • SQLERRM と SQLCODE は、例外メッセージとコードを提供する組み込み関数です。
  • 例外が処理されない場合、デフォルトでは、そのセッション内のすべてのアクティブなトランザクションがロールバックされます。
  • RAISE_APPLICATION_ERROR (- 、 ) RAISE の代わりに使用して、ユーザー コードとメッセージでエラーを発生させることができます。 エラー コードは 20000 より大きく、先頭に「-」を付ける必要があります。

まとめ

この章以降。 あなたは次のために働くことができるはずですwing Plの側面 SQL 例外

  • 例外の処理
  • 例外を定義する
  • 例外を発生させる
  • 例外の伝播