CONTINUEハンドラーは、制御のフローに影響するほど重大でない完了条件や例外条件を処理するのに役立ちます。
CONTINUEハンドラー アクション
条件が発生すると、CONTINUEハンドラーは以下の処理を行ないます。
- ハンドラー アクションを実行します。
- それを呼び出した文の次の文に制御を渡します。
- 条件を発生させた文に続く、残りのすべてのSQL文を実行します。
- 以下の表では、発生した例外によってCONTINUEハンドラーがアクティブにされたときの制御のフローについて説明しています。
条件 次のステップでの制御の行先 ハンドラー アクションが正常に完了した 条件を発生させた文の後に続く文に戻ります。 FOR、IF、LOOP、またはWHILEなどの制御文に組み込まれた文によって例外が発生した 制御文によって例外が発生した(例えば、条件式を評価するときに) 条件を発生させた制御文の後に続く文に渡ります。 - ハンドラ アクションで例外条件や完了条件が発生し、そのハンドラ アクション内に適当なハンドラーが存在する場合、新しく発生したその条件は処理されます。
制御がハンドラー アクション句に戻ります。
- プロセスの終わり。
CONTINUEハンドラーの例
以下の例は、CONTINUEハンドラーの動作を示しています。この例は、以下のストアド プロシージャ定義に基づいています。
CREATE PROCEDURE spSample4() BEGIN DECLARE hNumber INTEGER; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION INSERT INTO Proc_Error_Table (:SQLSTATE, CURRENT_TIMESTAMP, 'spSample4', 'Failed to Insert Row'); -- Statement_4_1 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1001; -- Statement_4_2 INSERT INTO EmpNames VALUES (1002, 'Thomas'); -- If the EmpNames table had been dropped, Statement_4_2 -- returns SQLEXCEPTION that is handled. -- Statement_4_3 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1003; END;
例: DECLARE HANDLERのANSIセッション モード
次の例では、以下の3つのSQL文がBTEQからANSIセッション モードで対話式に呼び出されることを想定しています。
INSERT INTO Department VALUES ('10', 'Development'); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample4();
SQL文で、ANSIセッション モードでのデッドロックなどのエラー条件や障害条件が報告された場合、その条件は条件ハンドラーを使用して処理されます。
以下の一連のイベントでは、上記の3つのSQL文がANSIセッション モードで呼び出された場合の、エラー条件がそれらの文に及ぼす影響について説明しています。
- Statement_4_2とマークされたストアド プロシージャ文は、SQLSTATEコード'42000'の例外を発生させます。リクエストはロールバックされます。
- '42000'条件に対するハンドラーが呼び出されます。
- このハンドラ タイプがCONTINUEの場合、ハンドラー アクションの完了後に制御はStatement_4_3に渡されます。
- 以下の項目は未コミットのまま残されます。
- 最初の2つの対話式SQL文
- Statement_4_1
- Statement_4_3
- spSample4内の条件ハンドラーから呼び出されるINSERT文。
- プロセスの終わり。
以下の一連のイベントでは、上記の3つのSQL文がANSIセッション モードで呼び出された場合の、障害条件がそれらの文に及ぼす影響について説明しています。
- Statement_4_2としてマークされたストアド プロシージャ文(CALL spSample4()文によって呼び出される)は、障害条件を示すSQLSTATEコードを戻します。
- Statement_4_1の結果と最初の2つの対話式で入力されたSQL文の結果はロールバックされ、トランザクションはロールバックされます。
- 戻されたSQLSTATEコードは、ブロック用に定義されたCONTINUEハンドラーを呼び出します。このハンドラは、該当する条件(ANSIセッション モードの障害)を処理するために作成されています。
- ハンドラー タイプがCONTINUEであるため、ストアド プロシージャはハンドラ アクション文とStatement_4_3を新規トランザクションとして送り、ストアド プロシージャは、ハンドラ アクションが完了した後の次の文に進みます。
- プロセスの終わり。
例: Teradataセッション モード
次の例では、以下の3つのSQL文がBTEQからTeradataセッション モードで対話式に呼び出されることを想定しています。文はTeradataセッション モードで呼び出されるため、各文は暗黙的なトランザクションとなります。
INSERT INTO Department VALUES ('10', 'Development'); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample4();
上記の3つのSQLステートメントがTeradataセッション モードで呼び出されると、次の一連のイベントが起こります。
- Statement_4_2とマークされたストアド プロシージャ文は、SQLSTATEコード'42000'の例外を発生させます。暗黙の文はロールバックされます。
- SQLSTATEコード'42000'は、該当する条件を処理するために定義されたCONTINUEハンドラーを呼び出します。
- このハンドラー タイプはCONTINUEであるため、Statement_4_1によって行なわれた変更は影響を受けません。
- 最初の2つのBTEQリクエストは暗黙的なトランザクションであるため、更新内容はロールバックされません。
- ハンドラー アクションが完了した後に、制御はStatement_4_3に渡されます。
- プロセスの終わり。
例: 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 spSample4();
上記の3つのSQLステートメントがTeradataセッション モードで呼び出されると、次の一連のイベントが起こります。
- Statement_4_1、Statement_4_2、および最初の3つのBTEQリクエストによって行なわれた更新内容は、すべてロールバックされます。
- Statement_4_2とマークされたストアド プロシージャ文は、障害条件を示すSQLSTATEの例外を発生させます。
- 障害条件は、該当する条件を処理するために定義されたCONTINUEハンドラーを呼び出します。
- ハンドラー タイプがCONTINUEであるため、Statement_4_3はハンドラー アクションの完了後に実行されます。ハンドラー アクションとStatement_4_3のどちらも暗黙的なトランザクションとして実行されます。これは、最初のBTの影響が、ステップ2でのロールバック時に取り消されたためです。
- プロセスの終わり。