PL/SQL では、エラーは例外と呼ばれます。例外が発生すると、通常の実行は停止し、制御が例外処理セクションに移ります。PL/SQL には、2 種類の例外があります:
事前定義済みの例外:サーバーに組み込まれたエラーが発生したときに、暗黙的に発生します。
ユーザー定義の例外:サーバーによって発生することはありません。開発者が定義した論理ルールに違反した場合に、
RAISE文を使用して明示的に発生させます。
一般的な例として、顧客が残高不足のアカウントから小切手を現金化しようとすると、アプリケーションはビジネスルールの違反を通知するためにユーザー定義の例外を発生させます。
例外の宣言と発生
例外は、関数、プロシージャ、パッケージ、または匿名ブロックの宣言セクションで宣言します。その後、RAISE を使用して発生させます:
DECLARE
exception_name EXCEPTION;
BEGIN
...
RAISE exception_name;
...
END;exception_name は、例外に割り当てる名前です。
重複した宣言:同じブロック内で同じ例外を 2 回宣言することはできません。2 つの異なるブロックで同じ例外を宣言することは許可されています。
例外のスコープ
例外は、ブロックスコープのルールに従います:
ブロック内で宣言された例外は、そのブロックに対してローカルであり、その中のすべてのネストされたブロックから可視です。
外側のブロックは、内側 (ネストされた) のブロックで宣言された例外を参照できません。
処理されない例外は、呼び出しスタックを上に伝播します。ハンドラなしで最上位に達した場合、クライアントアプリケーションに報告されます。
外側のブロックからの例外の参照
外側のブロックで宣言された例外を参照するには、そのブロックにラベルを割り当て、ラベルで例外名を修飾します:
block_name.exception_nameパッケージからの例外の参照
パッケージで宣言された例外は、パッケージレベルのスコープを持ちます。パッケージの外部から参照する場合は、パッケージ名で例外名を修飾します:
inventory_control.out_of_stock例:パッケージ内のユーザー定義の例外
次の例では、ユーザー定義の例外 (overdrawn) を ar パッケージで定義し、check_balance 内で発生させます。
check_balance は ar パッケージの一部であるため、パッケージ修飾子なしで overdrawn を発生させます:
CREATE OR REPLACE PACKAGE ar AS
overdrawn EXCEPTION;
PROCEDURE check_balance(p_balance NUMBER, p_amount NUMBER);
END;
CREATE OR REPLACE PACKAGE BODY ar AS
PROCEDURE check_balance(p_balance NUMBER, p_amount NUMBER)
IS
BEGIN
IF (p_amount > p_balance) THEN
RAISE overdrawn;
END IF;
END;次の purchase プロシージャは check_balance を呼び出します。purchase は ar パッケージの外部で定義されているため、パッケージで修飾された名前 ar.overdrawn を使用して例外を参照する必要があります:
CREATE PROCEDURE purchase(customerID INT, amount NUMERIC)
AS
BEGIN
ar.check_ balance(getcustomerbalance(customerid), amount);
record_purchase(customerid, amount);
EXCEPTION
WHEN ar.overdrawn THEN
raise_credit_limit(customerid, amount*1.5);
END;check_balance が overdrawn を発生させると、実行は purchase 内の例外ハンドラにジャンプします:
EXCEPTION
WHEN ar.overdrawn THEN
raise_credit_limit(customerid, amount*1.5);ハンドラは顧客の与信限度額を引き上げてから終了します。実行は、ar.check_balance 呼び出しの直後の文から再開されます。