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年 数値をゼロで除算しようとすると発生します。