PL / SQL-例外
この章では、PL / SQLの例外について説明します。例外は、プログラム実行中のエラー状態です。PL / SQLは、プログラマがEXCEPTIONプログラムでブロックし、エラー状態に対して適切なアクションが実行されます。例外には2つのタイプがあります-
- システム定義の例外
- ユーザー定義の例外
例外処理の構文
例外処理の一般的な構文は次のとおりです。ここでは、処理できる限り多くの例外をリストできます。デフォルトの例外は、を使用して処理されますWHEN others THEN −
DECLARE
<declarations section>
BEGIN
<executable command(s)>
EXCEPTION
<exception handling goes here >
WHEN exception1 THEN
exception1-handling-statements
WHEN exception2 THEN
exception2-handling-statements
WHEN exception3 THEN
exception3-handling-statements
........
WHEN others THEN
exception3-handling-statements
END;
例
概念を説明するコードを書いてみましょう。前の章で作成して使用したCUSTOMERSテーブルを使用します-
DECLARE
c_id customers.id%type := 8;
c_name customerS.Name%type;
c_addr customers.address%type;
BEGIN
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
/
上記のコードをSQLプロンプトで実行すると、次の結果が生成されます。
No such customer!
PL/SQL procedure successfully completed.
上記のプログラムは、IDが与えられた顧客の名前と住所を表示します。データベースにID値8の顧客がいないため、プログラムは実行時例外を発生させますNO_DATA_FOUND、でキャプチャされます EXCEPTION block。
例外の発生
内部データベースエラーが発生すると、データベースサーバーによって例外が自動的に発生しますが、プログラマーはコマンドを使用して例外を明示的に発生させることができます。 RAISE。以下は、例外を発生させるための簡単な構文です-
DECLARE
exception_name EXCEPTION;
BEGIN
IF condition THEN
RAISE exception_name;
END IF;
EXCEPTION
WHEN exception_name THEN
statement;
END;
上記の構文を使用して、Oracle標準例外または任意のユーザー定義例外を発生させることができます。次のセクションでは、ユーザー定義の例外を発生させる例を示します。同様の方法で、Oracle標準の例外を発生させることができます。
ユーザー定義の例外
PL / SQLを使用すると、プログラムの必要性に応じて独自の例外を定義できます。ユーザー定義の例外を宣言してから、RAISEステートメントまたはプロシージャを使用して明示的に発生させる必要があります。DBMS_STANDARD.RAISE_APPLICATION_ERROR。
例外を宣言するための構文は次のとおりです。
DECLARE
my-exception EXCEPTION;
例
次の例は、概念を示しています。このプログラムは、ユーザーが無効なIDを入力すると、例外として顧客IDを要求します。invalid_id 上げられます。
DECLARE
c_id customers.id%type := &cc_id;
c_name customerS.Name%type;
c_addr customers.address%type;
-- user defined exception
ex_invalid_id EXCEPTION;
BEGIN
IF c_id <= 0 THEN
RAISE ex_invalid_id;
ELSE
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
END IF;
EXCEPTION
WHEN ex_invalid_id THEN
dbms_output.put_line('ID must be greater than zero!');
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
/
上記のコードをSQLプロンプトで実行すると、次の結果が生成されます。
Enter value for cc_id: -6 (let's enter a value -6)
old 2: c_id customers.id%type := &cc_id;
new 2: c_id customers.id%type := -6;
ID must be greater than zero!
PL/SQL procedure successfully completed.
事前定義された例外
PL / SQLには多くの事前定義された例外があり、プログラムがデータベースルールに違反した場合に実行されます。たとえば、SELECT INTOステートメントが行を返さない場合、事前定義された例外NO_DATA_FOUNDが発生します。次の表に、事前定義された重要な例外のいくつかを示します。
例外 | Oracleエラー | SQLCODE | 説明 |
---|---|---|---|
ACCESS_INTO_NULL | 06530 | -6530 | nullオブジェクトに値が自動的に割り当てられると発生します。 |
CASE_NOT_FOUND | 06592 | -6592 | これは、CASEステートメントのWHEN句の選択肢がどれも選択されておらず、ELSE句がない場合に発生します。 |
COLLECTION_IS_NULL | 06531 | -6531 | これは、プログラムがEXISTS以外の収集メソッドを初期化されていないネストされたテーブルまたはVARRAYに適用しようとした場合、またはプログラムが初期化されていないネストされたテーブルまたはVARRAYの要素に値を割り当てようとした場合に発生します。 |
DUP_VAL_ON_INDEX | 00001 | -1 | 重複する値を一意のインデックスを持つ列に格納しようとすると発生します。 |
INVALID_CURSOR | 01001 | -1001 | 開いていないカーソルを閉じるなど、許可されていないカーソル操作を行おうとすると発生します。 |
無効な番号 | 01722 | -1722 | 文字列が有効な数値を表していないために文字列の数値への変換が失敗した場合に発生します。 |
LOGIN_DENIED | 01017 | -1017 | プログラムが無効なユーザー名またはパスワードでデータベースにログオンしようとすると発生します。 |
何もデータが見つかりませんでした | 01403 | +100 | SELECTINTOステートメントが行を返さない場合に発生します。 |
NOT_LOGGED_ON | 01012 | -1012 | これは、データベースに接続せずにデータベース呼び出しが発行されたときに発生します。 |
PROGRAM_ERROR | 06501 | -6501 | PL / SQLに内部問題がある場合に発生します。 |
ROWTYPE_MISMATCH | 06504 | -6504 | カーソルが互換性のないデータ型を持つ変数の値をフェッチすると発生します。 |
SELF_IS_NULL | 30625 | -30625 | メンバーメソッドが呼び出されたときに発生しますが、オブジェクトタイプのインスタンスは初期化されていません。 |
STORAGE_ERROR | 06500 | -6500 | PL / SQLのメモリが不足した場合、またはメモリが破損した場合に発生します。 |
TOO_MANY_ROWS | 01422 | -1422 | SELECTINTOステートメントが複数の行を返す場合に発生します。 |
VALUE_ERROR | 06502 | -6502 | これは、算術、変換、切り捨て、またはサイズ制約エラーが発生したときに発生します。 |
ZERO_DIVIDE | 01476 | 1476年 | 数値をゼロで除算しようとすると発生します。 |