16.20 - 文固有の条件処理 - 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

このセクションでは、ストアド プロシージャで条件を発生させたときのさまざまな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セッション モードで呼び出されると、次の一連のイベントが起こります。

  1. 呼び出されたストアド プロシージャの中のStatement_8_2は、SQLSTATE ‘42000’のエラー条件を発生させます。これは処理されます。文はロールバックされます。
  2. 条件ハンドラーがアクティブにされます。
  3. ハンドラー タイプがCONTINUEなので、実行は、ハンドラー アクションが完了した後で、WHILEループ内のSET文から再開されます。WHILEループが例外のために終了することはない
  4. 繰り返しのたびに、Statement_8_2は処理される例外を発生させます。

    Statement_8_3は、WHILEループの終了時に実行されます。

  5. 以下の項目はコミットされません。
    • 最初の2つの対話式SQL文
    • Statement_8_1
    • 条件ハンドラーのアクション文
    • Statement_8_3
  6. プロセスの終わり。
ストアド プロシージャspSample8がTeradataセッション モードのセッションで作成されると、1つの違いを除き、上記のプロセスが適用されます。各リクエストはTeradataセッション モードにおける暗黙的なトランザクションなので、以下の文がコミットされます。
  • 最初の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();

上記のストアド プロシージャに関して、以下の一連のイベントを考慮してください。

  1. 呼び出されたストアド プロシージャの中のIF文で、SQLSTATE '22012'のゼロ除算エラー条件が発生します。これは処理されます。
  2. ハンドラー タイプがCONTINUEであるため、ハンドラー アクションの完了後にStatement_9_3から実行が再開されます。
  3. Statement_9_2とSET文は、エラー条件を発生させたIF文の内部にあるため、実行されません。
  4. 以下の項目によって行なわれた更新内容は、未コミットのトランザクション内に影響を受けないまま残ります。
    • Statement_9_1
    • Statement_9_3
  5. プロセスの終わり。

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

  1. 呼び出されたストアド プロシージャ内のWHILE文の中の条件によって、例外が発生します。
  2. 条件ハンドラーがアクティブにされます。

    条件ハンドラーがCONTINUEタイプなので、制御はWHILEループの次の文(statement_8_3)に渡され、ストアド プロシージャの実行はstatement_8_3から継続します。

  3. WHILEループ内のStatement_8_2とSET文は実行されません。
  4. ストアド プロシージャの実行が完了したとき、以下の文はコミットされません。
    • 最初の2つの対話式SQL文
    • Statement_8_1
    • 条件ハンドラーのアクション文
    • Statement_8_3
  5. ストアド プロシージャspSample8がTeradataセッション モードのセッションで作成されると、1つの違いを除き、上記のプロセスが適用されます。各リクエストはTeradataセッション モードにおける暗黙的なトランザクションなので、以下の文がコミットされます。
    • 最初の2つの対話式SQL文
    • Statement_8_1
    • 条件ハンドラーのアクション文
    • Statement_8_3
  6. プロセスの終わり。