SQLEXCEPTIONは、すべての例外条件用のSQLSTATEコードを表わす一般条件です。文の実行中に例外条件が発生した場合に、該当する例外条件を処理するハンドラーが存在しないと、SQLEXCEPTIONに関連したハンドラーが呼び出されます。
SQLEXCEPTIONハンドラーは、EXITハンドラーまたはCONTINUEハンドラーとして記述することができます。
SQLEXCEPTIONハンドラー アクション
以下の表では、発生した例外によってSQLEXCEPTIONハンドラーがアクティブにされたときの制御のフローについて説明しています。
- ストアド プロシージャ内の文により、例外が発生します。
- 特定の例外条件を処理するハンドラーが存在しなければ、汎用の条件ハンドラーが呼び出されます。
- SQLEXCEPTIONハンドラーは、指定されたアクションを実行します。
- プロセスの次のステップは、ハンドラー タイプによって異なります。
ハンドラー タイプ 制御の行先 CONTINUE 現在のブロックにある次の文。 EXIT 現在のブロックの終わり。 - 特定のハンドラーとの対話は、状況に応じて変化します。
- プロセスの終わり。
例: 汎用条件ハンドラー
以下の例は、SQLEXCEPTIONハンドラーの動作を示しています。この例では、以下のストアド プロシージャを想定しています。
CREATE PROCEDURE spSample11() BEGIN DECLARE hNumber INTEGER; DECLARE EXIT HANDLER FOR SQLEXCEPTION INSERT INTO Proc_Error_Table (:SQLSTATE, CURRENT_TIMESTAMP, ’spSample11’, ’Generic handler performed’); -- Statement_11_1 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1001; -- Statement_11_2 INSERT INTO EmpNames VALUES (1002, ’Thomas’); -- If the EmpNames table had been dropped, -- Statement_11_2 returns SQLSTATE ’42000’ that is handled. -- Statement_11_3 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1003; END;
例: DECLARE HANDLER(SQLEXCEPTION型)のANSIセッション モード
この例では、以下の3つのSQL文がBTEQからANSIセッション モードで対話式に呼び出されることを想定しています。
INSERT INTO Department VALUES (’10’, ’Development’); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample11();
上記の3つのSQLステートメントがANSIセッション モードで呼び出されると、次の一連のイベントが起こります。
- 呼び出し先のストアド プロシージャの中のStatement_11_2は、SQLSTATE ’42000’のエラー条件を発生させます。SQLSTATEコード’42000’用の特定のハンドラーは存在しないため、この条件は、SQLEXCEPTIONハンドラーによって処理されます。
- Statement_11_2はロールバックされます。
- 条件ハンドラーがEXITハンドラーであるため、ハンドラー アクションの完了後に制御は呼び出し元に渡されます。
ストアド プロシージャに入れ子のブロックが含まれている場合、制御は呼び出し元の複合文の次の文に渡ります。
- 以下の項目はアクティブのまま残り、コミットされません。
- 最初の2つの対話式SQL文
- Statement_11_1
- ハンドラー内のINSERT文
- プロセスの終わり。
例: DECLARE HANDLERの両方のフォームを組み合わせたときのSQLEXCEPTIONと特定の条件ハンドラーの動作
次の例は、SQLEXCEPTIONハンドラーと特定の条件ハンドラーの両方のDECLARE HANDLERハンドラーが、ストアド プロシージャで組み合わされたときにどのように動作するかを示しています。この例では、以下のストアド プロシージャを想定しています。
CREATE PROCEDURE spSample12() BEGIN DECLARE hNumber INTEGER; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION -- Handler_1 BEGIN UPDATE exception_table SET exception_count = exception_count + 1; INSERT INTO Proc_Error_Table (:SQLSTATE, CURRENT_TIMESTAMP, ’spSample12’, 'Failed to insert row'); END; DECLARE EXIT HANDLER FOR SQLSTATE ’53000’ -- Handler_2 INSERT INTO Proc_Error_Table (:SQLSTATE, CURRENT_TIMESTAMP, ’spSample12’, ’Column does not exist’); -- Statement_12_1 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1001; -- Statement_12_2 INSERT INTO EmpNames VALUES (1002, ’Thomas’); -- If the EmpNames table has been dropped, Statement_12_2 -- returns the SQLSTATE code ’42000’ that is handled -- Statement_12_3 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_number = 1003; -- If Salary_Amount has been dropped, -- Statement_12_3 returns the SQLSTATE code ’53000’ that is handled END;
例: 特定および汎用条件ハンドラーのANSIセッション モード
この例では、以下の3つのSQL文がBTEQからANSIセッション モードで対話式に呼び出されることを想定しています。
INSERT INTO Department VALUES (’10’, ’Development’); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample12();
上記の3つのSQLステートメントがANSIセッション モードで呼び出されると、次の一連のイベントが起こります。
- ストアド プロシージャの中のStatement_12_2は、SQLSTATEコード’42000’の例外を発生させます。条件ハンドラーが存在しないため、この例外は処理されません。
- Statement_12_2はロールバックされます。
- 汎用のSQLEXCEPTIONハンドラー(コメントによりHandler_1と命名されている)がアクティブにされます。
Handler_1はCONTINUEハンドラーなので、ハンドラーアクションが正常に完了すると、Statement_12_3が実行されます。
- Statement_12_3は、SQLSTATEコード’53000’の例外条件を発生させます。
- 制御はHandler_2に渡されます。このハンドラーは、このSQLSTATE条件を処理するために明示的に定義されています。
- Handler_2はハンドラ アクションを実行します。Handler_2はEXITハンドラーなので、ハンドラー アクションが完了した後、制御がブロックの終了に渡ります。
他に文が含まれていなければ、プロシージャは終了します。
- 以下の項目はアクティブのまま残りますが、コミットされません。
- 最初の2つの対話式SQL文
- Statement_12_1
- Handler_1用のアクション文
- Handler_2用のアクション文
- プロセスの終わり。
関連トピック
SQLEXCEPTIONハンドラー アクションの詳細については、例: DECLARE HANDLERの両方のフォームを組み合わせたときのSQLEXCEPTIONと特定の条件ハンドラーの動作を参照してください。