PL/SQL - 例外処理:入門者向けガイド

こんにちは、未来のPL/SQLの達人さんたち!今日は、PL/SQLにおける例外の不思議な世界に飛び込みます。プログラミングが初めての方でも心配しないでください。私はこのトピックをステップバイステップで案内します。これまでに数多くの生徒を指導してきましたように。では、コーヒー(またはお好みでティー)を飲みながら、このエキサイティングな旅に出発しましょう!

PL/SQL - Exceptions

例外とは?

本題に入る前に、まず例外とは何かを理解しましょう。ケーキ作りを思い浮かべてください(私の話に従ってください、これがプログラミングに関連しています)。レシピをステップバイステップに従っていますが、突然、卵が無いことに気づきます!この予想外の状況は、プログラミングにおける例外と似ています。

PL/SQLでは、例外はプログラムの通常の流れを中断する予想外のイベントです。除数が0の除算や、ユニークな列に重複値を插入しようとするなどのエラーが考えられます。これらの問題がプログラムをクラッシュさせるのではなく、優雅に「処理」することができます。ケーキ作りの例で言うと、卵の代用品を使うようなものです。

例外処理の構文

それでは、PL/SQLでこれらの例外を実際にどのように処理するのかを見てみましょう。基本的な構造は以下の通りです:

BEGIN
-- 通常のコードここに
EXCEPTION
WHEN exception_name1 THEN
-- 例外1を処理
WHEN exception_name2 THEN
-- 例外2を処理
WHEN OTHERS THEN
-- 他のすべての例外を処理
END;

これを分解します:

  1. BEGINブロックに通常のコードを記述します。
  2. 例外が発生すると、プログラムはEXCEPTIONブロックにジャンプします。
  3. WHEN節を使って特定の例外を処理できます。
  4. WHEN OTHERS節は、特定していないすべての例外をキャッチします。

以下は簡単な例です:

DECLARE
v_result NUMBER;
BEGIN
v_result := 10 / 0;  -- これは除数が0のエラーを引き起こします
DBMS_OUTPUT.PUT_LINE('Result: ' || v_result);
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('Error: 0で割ることはできません!');
END;

この例では、10を0で割ろうとしますが、数学的には不可能です。プログラムはクラッシュすることなく、ZERO_DIVIDE例外をキャッチし、親切なエラーメッセージを表示します。

例外の発生

時々、特定の条件が満たされたときに自分で例外を発生させたいことがあります。その場合、RAISEステートメントを使います。サッカーの試合の判定員のようです。ファウルを見つけると、ホイッスルを吹きます!

以下はその方法です:

DECLARE
v_age NUMBER := 15;
BEGIN
IF v_age < 18 THEN
RAISE_APPLICATION_ERROR(-20001, '18歳以上である必要があります');
END IF;
DBMS_OUTPUT.PUT_LINE('Welcome to the club!');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;

この例では、誰かがクラブに入る年齢に達しているかを確認しています。18歳未満の場合、カスタムエラーメッセージで例外を発生させます。WHEN OTHERS節がこの例外をキャッチし、エラーメッセージを表示します。

ユーザー定義の例外

PL/SQLには多くの定義済み例外がありますが、時々、自分で新しい例外を作成する必要があります。ゲームに新しいルールを発明するようなものです。以下はその方法です:

DECLARE
e_invalid_name EXCEPTION;
v_name VARCHAR2(50) := 'J0hn';
BEGIN
IF NOT REGEXP_LIKE(v_name, '^[A-Za-z]+$') THEN
RAISE e_invalid_name;
END IF;
DBMS_OUTPUT.PUT_LINE('Name is valid: ' || v_name);
EXCEPTION
WHEN e_invalid_name THEN
DBMS_OUTPUT.PUT_LINE('Error: 名前は文字列のみを含める必要があります');
END;

この例では、カスタム例外e_invalid_nameを作成しています。名前が文字列以外を含む場合にこの例外を発生させます。これにより、この特定のシナリオをプログラムに合わせて処理できます。

定義済み例外

PL/SQLには、一般的なエラーシナリオに対するセットの定義済み例外が用意されています。これらは、予備の救急セットを持っているようなものです。以下は最もよく使われるもののいくつかです:

例外名 説明
NO_DATA_FOUND SELECT INTOステートメントが行を返さない場合に発生
TOO_MANY_ROWS SELECT INTOステートメントが1行以上を返す場合に発生
ZERO_DIVIDE 0で割ろうとする場合に発生
DUP_VAL_ON_INDEX ユニークインデックスに重複値を插入しようとする場合に発生
VALUE_ERROR 算術、変換、切り捨て、サイズ制約のエラーが発生した場合に発生

以下は定義済み例外を使った例です:

DECLARE
v_emp_name VARCHAR2(50);
BEGIN
SELECT first_name INTO v_emp_name
FROM employees
WHERE employee_id = 1000;  -- このIDが存在しないと仮定

DBMS_OUTPUT.PUT_LINE('Employee name: ' || v_emp_name);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Error: そのIDの従業員が見つかりません');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Error: 複数の従業員が見つかりました');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('予期せぬエラーが発生しました: ' || SQLERRM);
END;

この例では、従業員の名前を取得しようとしています。従業員が見つからない場合、NO_DATA_FOUND例外をキャッチします。何らかの理由で複数の従業員が見つかった場合、TOO_MANY_ROWS例外をキャッチします。他の予期せぬエラーはWHEN OTHERS節がキャッチします。

そして、それが全部です、皆さん!PL/SQLにおける例外処理の基本をカバーしました。例外処理は、運転中にシートベルトを着けるようなものです。すべてがスムーズに進んでいるときには不要に見えるかもしれませんが、問題が発生したときには大変役立ちます。

これらの概念を練習し、さまざまなシナリオを試してみてください。間もなく例外をプロのように処理できるようになるでしょう。ハッピーコーディング、そしてプログラムが常に予期せぬことを優雅に処理できることを願っています!

Credits: Image by storyset