EXITハンドラーは、プロシージャを終了するほど重大な条件を扱います。
EXITハンドラー アクション
条件が発生すると、EXITハンドラーは以下の処理を行ないます。
- ハンドラー アクションを実行します。
- ハンドラーが宣言されたBEGIN…END複合文を暗黙的に終了します。
- ストアド プロシージャの実行は、複合文の外の残りの文へと続行します。プロシージャに他の文が含まれていない場合、プロシージャは終了し、制御が呼び出し元に渡ります。
- 以下の表では、発生した例外条件や完了条件によってEXITハンドラーがアクティブにされたときの制御のフローについて説明しています。
条件 プロセスの次のステップ ハンドラー アクションが正常に完了した 制御が複合文の終了に渡るか、あるいは、トップ レベルであれば、ストアド プロシージャが終了します。 複合文で宣言されている開いたすべてのカーソルが暗黙的に閉じられます。
このプロシージャのCREATE PROCEDURE文が、INOUTまたはOUTパラメータを定義している SUCCESS応答におけるACTIVITY_COUNTの値は1に設定されます。 プロシージャでINOUTまたはOUTパラメータが定義されていない SUCCESS応答におけるACTIVITY_COUNTの値は0に設定されます。 呼び出し元がストアド プロシージャである 呼び出し元のストアド プロシージャ内のステータス変数は、戻された条件コードに適した値に設定されます。 SQLSTATEの場合、値は’00000’に設定されます。
SQLCODEの場合、値は0に設定されます。
制御文によって例外が発生した 制御は呼び出されたEXITハンドラーの入っている複合文を終了します。 - ハンドラー アクションで条件が発生した場合、そのハンドラ アクション句の中でハンドラーが定義されていれば、その条件は処理されます。
- プロセスの終わり。
EXITハンドラーの例
以下の例は、EXITハンドラーの動作を示しています。この例は、以下のストアド プロシージャ定義に基づいています。
CREATE PROCEDURE spSample5() BEGIN DECLARE hNumber INTEGER; DECLARE EXIT HANDLER FOR SQLSTATE ’42000’ INSERT INTO Proc_Error_Table (:SQLSTATE, CURRENT_TIMESTAMP, ’spSample5’, ’Failed to Insert Row’); -- Statement_5_1 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1001; -- Statement_5_2 INSERT INTO EmpNames VALUES (1002, ’Thomas’); -- If the EmpNames table had been dropped, Statement_5_2 -- returns an SQLSTATE code of ’42000’ that is handled. -- Statement_5_3 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1003; END;
続く例では、ストアド プロシージャに複合文が1つしか含まれていないので、ハンドラー アクションが完了すると、制御はストアド プロシージャを終了して、呼び出し元に渡ります。
複合文の中で定義されているハンドラーが、発生した条件を処理できない場合、その条件は適当なハンドラーを探すために外側に伝搬されます。
例: EXITハンドラーのANSIセッション モード
この例では、以下の3つのSQL文がBTEQからANSIセッション モードで対話式に呼び出されることを想定しています。
INSERT INTO Department VALUES (’10’, ’Development’); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample5();
障害条件ではない例外条件が報告されると、次のような一連のイベントが起こります。
- Statement_5_2とマークされたストアド プロシージャ文は、SQLSTATEコード’42000’の例外を発生させます。リクエストはロールバックされます。
- SQLSTATEコード’42000’は、特定の条件を処理するために定義されたEXITハンドラーを呼び出します。
- このハンドラー タイプはEXITであるため、Statement_5_1によって行なわれた変更は影響を受けません。
ハンドラー アクションが完了した後に、制御は呼び出し元に渡されます。ストアド プロシージャにおいて、呼び出し元の複合文の外に他の文がある場合、制御は呼び出し元の複合文の外の次の文に渡ります。
対話式で呼び出された最初のSQL文によって開始された暗黙的なトランザクションは、未解決のまま残ります。
- プロセスの終わり。
障害条件である例外条件が報告されると、次のような事柄が起こります。
- Statement_5_2とマークされたストアド プロシージャ文は、障害条件を示すSQLSTATEの例外を発生させます。
- Statement_5_1、Statement_5_2、および対話式で入力された最初の2つのSQL文の結果はロールバックされます。
- 戻されたSQLSTATEコードにより、その特定の条件に対して定義されているEXITハンドラーが呼び出されます。
- ハンドラー アクションの完了後、制御が呼び出し元の複合文を終了し、次の文があれば、次の文に渡ります。
- EXITハンドラーで実行されたSQL文のうち、コミットされていないものがある場合、新規トランザクションは未解決のまま残ります。
- プロセスの終わり。
例: DECLARE HANDLER(EXIT型)のTeradataセッション モード
この例では、以下の3つのSQL文がBTEQからTeradataセッション モードで対話式に呼び出されることを想定しています。文はTeradataセッション モードで呼び出されるため、各文は暗黙的なトランザクションとなります。
INSERT INTO Department VALUES (’10’, ’Development’); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample5();
上記の3つのSQLステートメントがTeradataセッション モードで呼び出されると、次の一連のイベントが起こります。
- Statement_5_2とマークされたストアド プロシージャ文は、SQLSTATEコード’42000’の例外を発生させます。暗黙の文はロールバックされます。
- SQLSTATEコード’42000’は、その特定の条件のために定義されたEXITハンドラーを呼び出します。
- このハンドラー タイプがEXITであり、Statement_5_1が暗黙的なトランザクションで実行されたため、この文によって行なわれた更新内容は影響を受けません。
- 最初の2つのBTEQリクエストは暗黙的なトランザクションであるため、更新内容はロールバックされません。
- ハンドラー アクションの完了後、制御が呼び出し元の複合文を終了し、次の文があれば、次の文に渡ります。
- プロセスの終わり。
例: BT文のTeradataセッション モード
この例では、以下の3つのSQL文がBTEQからTeradataセッション モードで対話式に呼び出されることを想定しています。シーケンスの開始のBT文は、SQL文を単一の明示的なトランザクションにしていることに注意してください。
BT; INSERT INTO Department VALUES (’10’, ’Development’); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample5();
上記の3つのSQLステートメントがTeradataセッション モードで呼び出されると、次の一連のイベントが起こります。
- Statement_5_2とマークされたストアド プロシージャ文は、障害条件を示すSQLSTATEコード’42000’の例外を発生させます。
- Statement_5_1、Statement_5_2、および最初の3つのBTEQリクエストによって行なわれた更新内容は、すべてロールバックされます。
- 障害条件は、該当する条件を処理するために定義されたEXITハンドラーを呼び出します。
- ハンドラー タイプがEXITなので、ハンドラ アクションが完了すると、制御が複合文を終了し、次の文があれば、次の文に渡ります。ハンドラーアクションは暗黙的なトランザクションとして実行されます。これは、最初のBTの影響が、ステップ2でのロールバック時に取り消されたためです。
- プロセスの終わり。
COMMIT文を含むEXITハンドラーの例
以下の例は、COMMITトランザクション制御文の入ったEXITハンドラーの動作を示しています。この例では、以下のストアド プロシージャを想定しています。
CREATE PROCEDURE spSample6() BEGIN DECLARE hNumber INTEGER; DECLARE EXIT HANDLER FOR SQLSTATE ’42000’ INSERT INTO Proc_Error_Table (:SQLSTATE, CURRENT_TIMESTAMP, ’spSample6’, ’Failed to Insert Row’); -- Statement_6_1 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1001; -- Statement_6_2 COMMIT; -- Statement_6_3 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1003; -- Statement_6_4 INSERT INTO EmpNames VALUES (1002, ’Thomas’); -- If the EmpNames table had been dropped, Statement_6_2 -- returns an SQLSTATE code of ’42000’ that is handled. END;
例: COMMIT文を含むEXITハンドラーのANSIセッション モード
この例では、以下の3つのSQL文がBTEQからANSIセッション モードで対話式に呼び出されることを想定しています。
INSERT INTO Department VALUES (’10’, ’Development’); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample6();
障害条件ではない例外条件が報告されると、次のような一連のイベントが起こります。
- ストアド プロシージャから出された最初の2つのBTEQリクエストと、Statement_6_1およびStatement_6_2は、通常通りに実行され、コミットされます。
- Statement_6_3は新規トランザクションを開始します。
- Statement_6_4とマークされたストアド プロシージャ文は、SQLSTATEコード’42000’の例外を発生させます。
- Statement_6_4はロールバックされます。
- SQLSTATEコード’42000’は、特定の条件を処理するために定義されたEXITハンドラーを呼び出します。
- このハンドラー タイプはEXITなので、ハンドラ アクションが完了すると、制御が複合文を終了し、その複合文の外の次の文があれば、そこに渡ります。ストアド プロシージャに他の文が含まれていない場合、プロシージャは終了し、制御が呼び出し元に渡ります。
ハンドラー アクションは、Statement_6_3によって開始されたトランザクション内で実行されます。
- プロセスの終わり。
例外条件(障害条件)が報告されると、次のような事柄が起こります。
- Statement_6_4とマークされたストアド プロシージャ文は、障害条件を示すSQLSTATEの例外を発生させます。
- Statement_6_1、Statement_6_2、および対話式で入力された最初の2つのSQL文の結果はロールバックされません。
Statement_6_4で障害が発生すると、Statement_6_4のトランザクションおよびStatement_6_3 (Statement_6_3がコミットされなかったため)のトランザクションがロールバックされます。
- ハンドラー アクション文は新規トランザクションを開始します。
- 障害条件は、該当する条件を処理するために定義されたEXITハンドラーを呼び出します。
ハンドラー アクションの完了後、制御が呼び出し元の複合文を終了し、次の文があれば、次の文に渡ります。
ストアド プロシージャに他の文が含まれていない場合、プロシージャは終了し、制御が呼び出し元に渡ります。
- プロセスの終わり。
関連トピック
EXITハンドラー条件の詳細については、ハンドラー アクションで発生する条件を参照してください。