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

⚡ スマートサマリー

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

  • ⚙️ 実行時エラー: PL/SQLエンジンが実行できない命令(例えば、数値をゼロで割る命令など)に遭遇した場合、例外が発生します。
  • 🧱 ブロック構造: 例外は、EXCEPTION セクションで WHEN 句を使用して処理され、WHEN OTHERS は常に最後に配置されます。
  • 📚 事前定義された例外: Oracle STANDARD パッケージには、NO_DATA_FOUND や ZERO_DIVIDE などの一般的なエラーの名前が付けられており、直接捕捉できるようになっています。
  • 🛠️ ユーザー定義の例外: プログラマーは独自の例外変数を宣言し、RAISEキーワードを使用して明示的に例外を発生させます。
  • <XNUMXxEXNUMX><XNUMXxAC><XNUMXxEXNUMX><XNUMXxEXNUMX><XNUMXxXNUMX><XNUMXxXNUMX>️️️️ 伝搬: 処理されない例外は、それを囲んでいるブロックに渡され、RAISE はそれを親プログラムに再通知します。
  • 🤖 AI支援: AIコーディングツールは、例外ブロックを作成し、レビュー中に未処理のエラーパスをフラグ付けします。

での例外処理 Oracle PL / SQLの

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

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

例えば、PL/SQLエンジンが数値をゼロで割る命令を受け取った場合、エラーを例外として発生させます。この例外は、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部分が存在する場合はそれを実行します。このハンドラはすべての例外に共通です。
  • ハンドラの実行後、制御は現在のブロックから離れます。
  • 実行時にブロックに対して実行できる例外ハンドラは1つだけです。例外ハンドラの実行が完了すると、エンジンは残りのハンドラをスキップし、現在のブロックを終了します。

注意: WHEN OTHERS は常にシーケンスの最後に配置する必要があります。WHEN OTHERS の実行が完了するとブロックから制御が抜けるため、WHEN OTHERS の後に記述されたハンドラは決して実行されません。

例外の種類

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

  • 定義済みの例外
  • ユーザー定義の例外

事前定義された例外

Oracle には、いくつかの一般的な例外が定義されています。定義済みの例外にはそれぞれ一意の名前とエラー番号があり、それらはすべて STANDARD パッケージで宣言されています。 Oracleコード内では、これらの定義済み例外名を直接使用して、対応するエラーを処理できます。これらの多くは、一般的な例外に直接対応しています。 SQL 日常的に遭遇するエラー。

以下に、あらかじめ定義された例外事項をいくつか示します。

例外 エラー 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 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 数をゼロで割る

ユーザー定義の例外

上記の定義済み例外に加えて、プログラマはカスタム例外を作成して処理することもできます。カスタム例外はサブルーチンレベルの宣言部分で作成され、そのサブルーチン内でのみ有効です。パッケージ仕様で定義された例外はパブリック例外であり、パッケージにアクセスできる場所であればどこからでも有効です。

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

DECLARE
<exception_name> EXCEPTION;
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN
<Handler>
END;
  • 上記の構文では、変数「exception_name」はEXCEPTION型として定義されています。
  • そうすれば、事前定義された例外と同じように使用できます。

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

CREATE PACKAGE <package_name>
 IS
<exception_name> EXCEPTION;
.
.
END <package_name>;
  • 上記の構文では、変数「exception_name」はパッケージ仕様のEXCEPTION型として定義されています。 。
  • パッケージ「package_name」が呼び出されるデータベース内のあらゆる場所で使用できます。

PL/SQLによる例外の発生

定義済みの例外は、対応するエラーが発生すると自動的に発生します。ただし、ユーザー定義の例外は、キーワードRAISEを使用して明示的に発生させる必要があります。RAISEは、以下に示す方法で使用できます。

ハンドラ内で RAISE を単独で使用すると、既に発生した例外が親ブロックに伝播されます。RAISE は、以下に示すように、例外ブロック内でのみ使用できます。

以下のスクリーンショットは、RAISE を単独で使用して、囲んでいるブロックに対して例外を再発生させた例を示しています。

RAISE のみを使用して例外を親ブロックに伝播する

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

構文の説明:

  • 上記の構文では、キーワードRAISEが例外処理ブロック内で使用されています。
  • プログラムが例外「exception_name」に遭遇した場合、例外は処理され、正常に完了します。
  • ハンドラ内のキーワードRAISEは、同じ例外を親プログラムに伝播します。

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

キーワード「RAISE」に例外名を続けて指定することで、ユーザー定義または事前定義された特定の例外を発生させることもできます。この形式は、実行部分と例外処理部分の両方で使用できます。

以下のスクリーンショットは、RAISEコマンドに例外名を続けて指定することで、特定の例外を発生させる例を示しています。

RAISE に例外名を続けて指定することで、特定の名前付き例外を発生させる。

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

構文の説明:

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

例1: この例では、次のことがわかります。

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

以下のスクリーンショットは、sample_exceptionを宣言し、ネストされたブロック内でそれを発生させ、メインブロックに伝播させる完全なブロックを示しています。

ネストされたブロック内でユーザー定義例外を宣言および発生させる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;
/

Code 説明:

  • Code 2行目: 変数「sample_exception」をEXCEPTION型として宣言します。
  • Code 3行目: プロシージャ nested_block を宣言します。
  • Code 6行目: 「ネストされたブロック内」という文を出力します。
  • Code 7行目: 「ネストされたブロックから sample_exception を発生させています」というステートメントを出力します。
  • Code 8行目: 「RAISEサンプル例外」を使用して例外を発生させます。
  • Code 10行目: ネストされたブロック内の例外 sample_exception の例外ハンドラ。
  • 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 の範囲である必要があります。

よくあるご質問

PRAGMA EXCEPTION_INIT は、ユーザーが宣言した例外名を特定の例外に関連付けます。 Oracle エラー番号。バインド後、WHEN OTHERSを使用してSQLCODEをチェックする代わりに、WHEN句でORAエラーを名前で捕捉できます。

SQLCODE は現在の例外の数値エラーコードを返し、SQLERRM はテキストメッセージを返します。どちらも例外ハンドラ内(多くの場合 WHEN OTHERS ブロック内)で呼び出され、何が問題だったかをログに記録したり表示したりします。

すべてのエラーを黙って処理するWHEN OTHERSは避けてください。SQLCODEとSQLERRMをログに記録したり、RAISEで例外を再スローしたりしないと、バグが隠蔽されてしまいます。例外のログ記録、クリーンアップ、そして伝播のみに使用してください。

RAISE_APPLICATION_ERROR は、-20000 ~ -20999 のエラー番号と最大 2048 バイトのメッセージを受け入れます。実行を停止し、呼び出し元のアプリケーションにカスタム エラーを返すことで、ユーザー定義条件をネイティブのエラーのように見せます。 Oracle エラー。

同じブロック内では実行しないでください。制御がEXCEPTIONセクションに移ると、そのブロックは終了します。実行を継続するには、リスクのあるステートメントを内側のBEGIN…EXCEPTION…ENDブロックで囲みます。エラー処理が完了すると、外側のブロックの実行が継続されます。

エラーとは、コードの実行時またはコンパイル時のあらゆる問題のことです。例外とは、PL/SQLの実行時メカニズムであり、実行時エラーを表し、制御をEXCEPTIONセクションに移すことで、プログラムが突然終了するのではなく、応答できるようにします。

はい。AIアシスタントや機械学習によるコードレビュー担当者は、例外ブロックを作成し、捕捉すべき定義済み例外を提案し、ハンドラーのないコードパスを指摘します。ただし、開発者はデプロイ前にロジックとエラーメッセージを確認する必要があります。

GitHubコパイロット 短いコメントから、WHEN句、RAISE_APPLICATION_ERROR呼び出し、および完全なEXCEPTIONブロックを自動補完します。ルーチンハンドラーのコーディングを高速化しますが、生成されたエラーコードとメッセージは正確性を確認するためにレビューが必要です。