PL/SQLの例外処理(後編):超入門「PL/SQL」(9)(1/2 ページ)
本連載は、「PL/SQL(Procedure Language/Structured Query Language)」を理解し、活用するための実践講座です。前回に引き続き「例外処理」について解説します。
本連載は、Oracle Database向けにデータベース言語「SQL(Structured Query Language)」を拡張したプログラミング言語である「PL/SQL(Procedure Language/Structured Query Language)」を理解し、活用するための実践講座です。SQLは知っているけれど、OracleでのPL/SQLは初めてという人向けに、機能の概要と具体的な書き方を解説します。
PL/SQLで発生したエラーを「例外」と呼びます。前回に続いて、今回も例外が起きたときの対応方法を記述する「例外処理部」について紹介します。例外には「内部例外」「ユーザー定義例外」「定義外例外」の3種類があり、前回は内部例外について解説しました(内部例外の解説はこちら)。今回は、残り2つの例外の他、例外処理について考慮しなければならないことを解説していきます。
ユーザー定義例外
ユーザーが独自に定義した例外をユーザー定義例外と呼びます。例えば、「社員番号7369の社員の給与がNULLの場合は例外とし、トランザクションをロールバックする」といった処理が可能です。まずは書式を確認しましょう。
(1) 例外名を定義(宣言部) <例外名> EXCEPTION ; (2) ユーザー定義例外の発生(実行部、例外処理部) RAISE <例外名> ; (3) 例外への対処方法を定義(例外処理部) WHEN <例外名> [ OR <例外名> ] THEN 処理文 ;
まず宣言部で例外名を定義します。その後、実行部などで特定の処理を行った場合にRAISE文で例外を発生させます。これによって制御は即座に例外処理部に移動します。例外処理部では、内部例外と同様にWHEN句で例外名を指定し、THEN句で例外に対する対処を記述します。
以下のサンプルプログラムで具体的に見ていきましょう。
DECLARE e_sal NUMBER; null_sal EXCEPTION; BEGIN SELECT sal INTO e_sal FROM emp WHERE empno = 7369; IF e_sal IS NULL THEN RAISE null_sal; ELSE null; END IF; UPDATE e_emp SET deptno = 30 WHERE empno = 7369; EXCEPTION WHEN null_sal THEN rollback; END; / PL/SQLプロシージャが正常に完了しました。
サンプルプログラムでは、まず宣言部で例外名null_salを定義しています。その後、実行部のIF文でe_sal変数に代入されている値を評価し、NULLだった場合はRAISE文で例外を発生させます。RAISE文が実行されると処理は即座に例外処理部に移動します。例外処理部では、前回紹介した内部例外と同様にWHEN句で例外名null_salを指定し、THEN句でロールバックするように指定しています。
定義外例外
PL/SQLブロック内で対処方法が指定されていない例外を定義外例外と呼びます。
通常、定義外例外が発生すると、PL/SQLブロックが異常終了してしまいます。明示的に対処方法を指定していないその他の例外が発生した場合であってもPL/SQLブロックを正常終了させたい場合は、OTHERSハンドラを使用します。
定義外例外を記述するには、次のサンプルプログラムのように例外処理部のWHEN句にOTHERSハンドラを指定し、THEN句で対処方法を記述します。全ての例外に対応するため、定義外例外は例外処理部の最後に記述するようにしましょう。
SQL> DECLARE e_empno NUMBER; BEGIN SELECT empno INTO e_empno FROM emp; EXCEPTION WHEN too_many_rows THEN rollback; WHEN others THEN rollback; END; / PL/SQLプロシージャが正常に完了しました。
OTHERSハンドラでは全ての定義外例外に対処できますが、実際にどういった例外が発生していたのかは分かりません。どのような例外なのかを調査したい場合は、エラー報告関数を使用します。エラー報告関数はその名の通り、発生した例外の情報を提供する関数で、2種類あります。
関数名 | 機能 |
---|---|
SQLCODE | エラー番号を返す |
SQLERRM | エラーメッセージを返す |
次のサンプルプログラムでは、DBMS_OUTPUT.PUT_LINEにエラー報告関数を指定して画面上に例外情報を表示しています(※1)。なお、関数の戻り値を変数に代入し、エラー記録用の表に挿入するような処理も可能です。
※1 エラー報告関数はSQLに直接指定できない。いったん変数に代入してから操作する必要がある。
SQL> DECLARE e_empno NUMBER; BEGIN SELECT empno INTO e_empno FROM emp; EXCEPTION WHEN others THEN DBMS_OUTPUT.PUT_LINE(sqlcode); DBMS_OUTPUT.PUT_LINE(sqlerrm); END; / -1422 ORA-01422: 完全フェッチがリクエストよりも多くの行を戻しました PL/SQLプロシージャが正常に完了しました。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- DBエンジンを最大限に生かすバッチアプリの作り方
第1回では、バッチアプリケーションを設計するうえで考慮すべき4つのポイントについて解説しました。今回は、Oracleデータベースを最大限に利用したバッチアプリケーションの実装テクニックについて解説します。 - ODTを使ったVisual StudioからのPL/SQL開発
オラクル社が提供する3つの.NET環境用開発ツール「ODP.NET」「ODT」「ODE.NET」。Oracle 10gリリース2に対応した最新版を使って、Oracleデータベースを前提とした.NETアプリケーションの開発手法を解説する。(編集部) - 更新/挿入/削除のSQLを高速化する3つの技とは?
本連載では、Oracleデータベースのパフォーマンス・チューニングの中から、特にSQLのチューニングに注目して、実践レベルの手法を解説する。読者はOracleデータベースのアーキテクチャを理解し、運用管理の実務経験を積んでいることが望ましい。対象とするバージョンは現状で広く使われているOracle9iの機能を基本とするが、Oracle 10gで有効な情報も随時紹介していく。(編集局) - 【Oracle Database】忘れていませんか? 「アラートログ調査」に必要な、たった3つのキホン
データベース管理システムの運用でトラブルが発生したらどうするか。データベースサポートスペシャリストが現場目線の解決Tipsをお届けします。今回は基本編として「アラートログの調査で押さえるべき3つのポイント」を解説します。【Oracle Database 12c対応版】