このセクションでは、ストアド プロシージャで条件を発生させたときのさまざまなSQL制御文の動作について説明します。
FORループでの例外におけるカーソルの処理
障害およびエラー条件にそれぞれ対応するオープン カーソルの処理について、以下の表で説明しています。
FORカーソル ループの実行時に発生した例外 | すべてのオープン カーソルに対する処理 |
---|---|
FAILURE | トランザクション ロールバックの一部として閉じられます。 |
ERROR | 閉じられません。 |
条件ハンドラーによって指定されたハンドラー アクションは、すべてのオープン カーソルが閉じられるまで実行されません。
例: WHILEループ例外
次の例では、以下のストアド プロシージャを想定しています。
CREATE PROCEDURE spSample8() BEGIN DECLARE hNumber INTEGER; DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' INSERT INTO Proc_Error_Table (:SQLSTATE, CURRENT_TIMESTAMP, 'spSample8', 'Failed to Insert Row'); SET hNumber = 1; -- Statement_8_1 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1001; WHILE hNumber < 10 DO -- Statement_8_2 INSERT INTO EmpNames VALUES (1002, 'Thomas'); SET hNumber = hNumber + 1; END WHILE; -- If the EmpNames table had been dropped, -- Statement_8_2 returns an SQLSTATE code of -- '42000' that is handled. -- Statement_8_3 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1003; END;
例: 文固有の条件ハンドラーのANSIセッション モード
この例では、以下の3つのSQL文がBTEQからANSIセッション モードで対話式に呼び出されることを想定しています。
INSERT INTO Department VALUES ('10', 'Development'); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample8();
上記の3つのSQLステートメントがANSIセッション モードで呼び出されると、次の一連のイベントが起こります。
上記の3つのSQLステートメントがANSIセッション モードで呼び出されると、次の一連のイベントが起こります。
- 呼び出されたストアド プロシージャの中のStatement_8_2は、SQLSTATE ‘42000’のエラー条件を発生させます。これは処理されます。文はロールバックされます。
- 条件ハンドラーがアクティブにされます。
- ハンドラー タイプがCONTINUEなので、実行は、ハンドラー アクションが完了した後で、WHILEループ内のSET文から再開されます。WHILEループが例外のために終了することはない。
- 繰り返しのたびに、Statement_8_2は処理される例外を発生させます。
Statement_8_3は、WHILEループの終了時に実行されます。
- 以下の項目はコミットされません。
- 最初の2つの対話式SQL文
- Statement_8_1
- 条件ハンドラーのアクション文
- Statement_8_3
- プロセスの終わり。
- 最初の2つの対話式SQL文
- Statement_8_1
- 条件ハンドラーのアクション文
- Statement_8_3
例: IF文で発生する例外
次の例では、以下のストアド プロシージャを想定しています。
CREATE PROCEDURE spSample9() BEGIN DECLARE hNumber, NumberAffected INTEGER; DECLARE CONTINUE HANDLER FOR SQLSTATE '22012' INSERT INTO Proc_Error_Table (:SQLSTATE, CURRENT_TIMESTAMP, 'spSample9', 'Failed Data Handling'); SET hNumber = 100; -- Statement_9_1 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number BETWEEN 1001 AND 1010; SET NumberAffected = ACTIVITY_COUNT; IF hNumber/NumberAffected < 10 THEN -- If the UPDATE in Statement_9_1 results in 0 rows -- being affected, the IF condition raises an -- exception with SQLSTATE '22012' that is -- handled. -- Statement_9_2 INSERT INTO data_table (NumberAffected, 'DATE'); SET hNumber = hNumber + 1; END IF; -- Statement_9_3 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1003; END;
上記の例では、以下の3つのSQL文がBTEQからANSIセッション モードで対話式に呼び出されることを想定しています。
INSERT INTO Department VALUES ('10', 'Development'); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample9();
上記のストアド プロシージャに関して、以下の一連のイベントを考慮してください。
- 呼び出されたストアド プロシージャの中のIF文で、SQLSTATE '22012'のゼロ除算エラー条件が発生します。これは処理されます。
- ハンドラー タイプがCONTINUEであるため、ハンドラー アクションの完了後にStatement_9_3から実行が再開されます。
- Statement_9_2とSET文は、エラー条件を発生させたIF文の内部にあるため、実行されません。
- 以下の項目によって行なわれた更新内容は、未コミットのトランザクション内に影響を受けないまま残ります。
- Statement_9_1
- Statement_9_3
- プロセスの終わり。
例: WHILEループ内の条件によって発生した例外
以下の例は、ループ内の条件によって例外が発生したときにWHILE文がどのように動作するかを示しています。この動作はIFおよびFOR文にも当てはまります。この例では、以下のストアド プロシージャを想定しています。
CREATE PROCEDURE spSample8() BEGIN DECLARE hNumber INTEGER; DECLARE CONTINUE HANDLER FOR SQLSTATE '22012' INSERT INTO Proc_Error_Table (:SQLSTATE, CURRENT_TIMESTAMP, 'spSample8', 'Failed in WHILE condition'); SET hNumber = 1; SET hNo = 0; -- Statement_8_1 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1001; WHILE ((hNumber/hNo) < 10) DO -- Statement_8_2 INSERT INTO EmpNames VALUES (1002, 'Thomas'); SET hNumber = hNumber + 1; END WHILE; -- The condition in WHILE statement raises -- an exception and returns SQLSTATE code -- of 22012 that is handled. -- Statement_8_3 UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1003; END;
例: ANSIセッション モード
上記の例では、以下の3つのSQL文がBTEQからANSIセッション モードで対話式に呼び出されることを想定しています。
INSERT INTO Department VALUES ('10', 'Development'); UPDATE Employee SET Salary_Amount = 10000 WHERE Employee_Number = 1000; CALL spSample8();
上記の3つのSQLステートメントがANSIセッション モードで呼び出されると、次の一連のイベントが起こります。
- 呼び出されたストアド プロシージャ内のWHILE文の中の条件によって、例外が発生します。
- 条件ハンドラーがアクティブにされます。
条件ハンドラーがCONTINUEタイプなので、制御はWHILEループの次の文(statement_8_3)に渡され、ストアド プロシージャの実行はstatement_8_3から継続します。
- WHILEループ内のStatement_8_2とSET文は実行されません。
- ストアド プロシージャの実行が完了したとき、以下の文はコミットされません。
- 最初の2つの対話式SQL文
- Statement_8_1
- 条件ハンドラーのアクション文
- Statement_8_3
- ストアド プロシージャspSample8がTeradataセッション モードのセッションで作成されると、1つの違いを除き、上記のプロセスが適用されます。各リクエストはTeradataセッション モードにおける暗黙的なトランザクションなので、以下の文がコミットされます。
- 最初の2つの対話式SQL文
- Statement_8_1
- 条件ハンドラーのアクション文
- Statement_8_3
- プロセスの終わり。