16.20 - DECLARE HANDLER (CONTINUEタイプ) - Teradata Vantage NewSQL Engine

Teradata Vantage™ SQL ストアド プロシージャおよび埋め込みSQL

prodname
Teradata Database
Teradata Vantage NewSQL Engine
vrm_release
16.20
category
プログラミング リファレンス
featnum
B035-1148-162K-JPN

CONTINUEハンドラーは、制御のフローに影響するほど重大でない完了条件や例外条件を処理するのに役立ちます。

CONTINUEハンドラー アクション

条件が発生すると、CONTINUEハンドラーは以下の処理を行ないます。

  1. ハンドラー アクションを実行します。
  2. それを呼び出した文の次の文に制御を渡します。
  3. 条件を発生させた文に続く、残りのすべてのSQL文を実行します。
  4. 以下の表では、発生した例外によってCONTINUEハンドラーがアクティブにされたときの制御のフローについて説明しています。
    条件 次のステップでの制御の行先
    ハンドラー アクションが正常に完了した 条件を発生させた文の後に続く文に戻ります。
    FOR、IF、LOOP、またはWHILEなどの制御文に組み込まれた文によって例外が発生した
    制御文によって例外が発生した(例えば、条件式を評価するときに) 条件を発生させた制御文の後に続く文に渡ります。
  5. ハンドラ アクションで例外条件や完了条件が発生し、そのハンドラ アクション内に適当なハンドラーが存在する場合、新しく発生したその条件は処理されます。

    制御がハンドラー アクション句に戻ります。

  6. プロセスの終わり。

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セッション モードで呼び出された場合の、エラー条件がそれらの文に及ぼす影響について説明しています。

  1. Statement_4_2とマークされたストアド プロシージャ文は、SQLSTATEコード'42000'の例外を発生させます。リクエストはロールバックされます。
  2. '42000'条件に対するハンドラーが呼び出されます。
  3. このハンドラ タイプがCONTINUEの場合、ハンドラー アクションの完了後に制御はStatement_4_3に渡されます。
  4. 以下の項目は未コミットのまま残されます。
    • 最初の2つの対話式SQL文
    • Statement_4_1
    • Statement_4_3
    • spSample4内の条件ハンドラーから呼び出されるINSERT文。
  5. プロセスの終わり。

以下の一連のイベントでは、上記の3つのSQL文がANSIセッション モードで呼び出された場合の、障害条件がそれらの文に及ぼす影響について説明しています。

  1. Statement_4_2としてマークされたストアド プロシージャ文(CALL spSample4()文によって呼び出される)は、障害条件を示すSQLSTATEコードを戻します。
  2. Statement_4_1の結果と最初の2つの対話式で入力されたSQL文の結果はロールバックされ、トランザクションはロールバックされます。
  3. 戻されたSQLSTATEコードは、ブロック用に定義されたCONTINUEハンドラーを呼び出します。このハンドラは、該当する条件(ANSIセッション モードの障害)を処理するために作成されています。
  4. ハンドラー タイプがCONTINUEであるため、ストアド プロシージャはハンドラ アクション文とStatement_4_3を新規トランザクションとして送り、ストアド プロシージャは、ハンドラ アクションが完了した後の次の文に進みます。
  5. プロセスの終わり。

例: 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セッション モードで呼び出されると、次の一連のイベントが起こります。

  1. Statement_4_2とマークされたストアド プロシージャ文は、SQLSTATEコード'42000'の例外を発生させます。暗黙の文はロールバックされます。
  2. SQLSTATEコード'42000'は、該当する条件を処理するために定義されたCONTINUEハンドラーを呼び出します。
  3. このハンドラー タイプはCONTINUEであるため、Statement_4_1によって行なわれた変更は影響を受けません。
  4. 最初の2つのBTEQリクエストは暗黙的なトランザクションであるため、更新内容はロールバックされません。
  5. ハンドラー アクションが完了した後に、制御はStatement_4_3に渡されます。
  6. プロセスの終わり。

例: 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セッション モードで呼び出されると、次の一連のイベントが起こります。

  1. Statement_4_1、Statement_4_2、および最初の3つのBTEQリクエストによって行なわれた更新内容は、すべてロールバックされます。
  2. Statement_4_2とマークされたストアド プロシージャ文は、障害条件を示すSQLSTATEの例外を発生させます。
  3. 障害条件は、該当する条件を処理するために定義されたCONTINUEハンドラーを呼び出します。
  4. ハンドラー タイプがCONTINUEであるため、Statement_4_3はハンドラー アクションの完了後に実行されます。
    ハンドラー アクションとStatement_4_3のどちらも暗黙的なトランザクションとして実行されます。これは、最初のBTの影響が、ステップ2でのロールバック時に取り消されたためです。
  5. プロセスの終わり。