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

CONTINUEの例外条件とEXITの例外条件には、いずれも同じルールのセットが適用されます。ストアド プロシージャの動作は、ANSIおよびTeradataセッション モードの意味とだいたい一致します。

次の表は、それぞれ、エラーと失敗の条件におけるトランザクションの意味を説明しています。

条件のタイプ セッション モード Transaction Managerが行なうアクション
エラー ANSI リクエスト レベルのロールバック。

例外条件の発生した文だけがロールバックされます。

失敗
  • ANSI
  • Teradata
トランザクション レベルのロールバック。

トランザクション内で実行されたすべての更新がロールバックされます。

例: 外側の複合文に関連付けられているCONTINUEハンドラーの使用

この例は、外側の複合文に関連したCONTINUEハンドラーが、内側の複合文で発生した例外条件を処理する方法を表わしています。

CREATE PROCEDURE spSample1(IN pName CHARACTER(30), IN pAmt INTEGER)
BEGIN
   DECLARE CONTINUE HANDLER FOR SQLSTATE '23505'
     INSERT INTO Proc_Error_Tbl VALUES (:SQLSTATE,
      CURRENT_TIMESTAMP, 'spSample1', 'Duplicate Row Error');
     ...
      L1: BEGIN
     DECLARE counter INTEGER DEFAULT 5;
     DECLARE CONTINUE HANDLER FOR SQLSTATE '42000'
       L2: BEGIN
         INSERT INTO Proc_Error_Tbl VALUES (:SQLSTATE,
                     CURRENT_TIMESTAMP, 'spSample1',
                                  'Table does not exist');
       ...
       END L2;
   WHILE (counter < 1022012) 
   DO
     INSERT INTO tab1 VALUES (pName, pAmt) ;
      -- Duplicate row error
           SET counter = counter + 1;
   END WHILE;
   ...
   END L1;
   ...
END;

テーブルtab1が次のようにして作成されるとします。

CREATE SET TABLE tab1(c1 CHARACTER(30), c2 INTEGER);

ストアド プロシージャspSample1を実行します。

CALL spSample1('Richard', 100);

L1のWHILE文の中のINSERTで重複行例外が発生します。複合文L1の中にはハンドラーがないので、これはラベルのない外側の複合文に伝搬されます。

SQLSTATE '23505'に対して宣言されているCONTINUEハンドラーが呼び出されます。このハンドラーが例外条件を処理し、例外条件の発生したINSERTの次の文からストアド プロシージャの実行が続けられます。

例: 内側の複合文で発生する例外

この例は、ストアド プロシージャ全体に適当なハンドラーが存在しないために、内側の複合文で発生した例外が処理されずに残される様子を示しています。

CREATE PROCEDURE spSample1(IN pName CHARACTER(30), IN pAmt INTEGER)
L1: BEGIN
...
L2: BEGIN
  DECLARE vName CHARACTER(30);
  INSERT INTO tab1 VALUES (pName, pAmt);
  -- The table does not exist
  -- exception is raised, and not handled
  SET vName = pName;
END L2;
INSERT ...
END L1;

次のようにテーブルtab1が削除されるとします。

DROP TABLE tab1;

ストアド プロシージャspSample1を実行します。

CALL spSample1('Richard', 10000);

ストアド プロシージャの実行中、最初のINSERT文でSQLSTATE '42000'の例外が発生しますが、L2というラベルの複合文には、この例外を処理するよう定義されたハンドラーがありません。

発生した例外に対して定義されているハンドラーは、外側のL1というラベルの複合文の中にもありません。そのため、ストアド プロシージャは、SQLSTATE '42000'に対応するエラー コードで終了します。

例: SQLSTATEコードの再利用

次の例は、入れ子の複合文における同一のSQLSTATEコードの有効な再利用方法を示しています。

ストアド プロシージャの実行の前に、テーブルtDummyが削除されるとします。L1およびL2というラベルの複合文で同じ種類の例外条件が発生し、条件はそれぞれの場所で処理されます。2つのコンパイル警告を伴うストアド プロシージャが作成されます。

CREATE PROCEDURE spSample (OUT po1 VARCHAR(50),
                           OUT po2 VARCHAR(50))
BEGIN
     DECLARE i INTEGER DEFAULT 0;
     L1: BEGIN
         DECLARE var1 VARCHAR(25) DEFAULT 'ABCD';
         DECLARE CONTINUE HANDLER FOR SQLSTATE '42000'
             SET po1 = "Table does not exist in L1';
         INSERT INTO tDummy (10, var1);
      -- Table does not exist.
         L2: BEGIN
             DECLARE var1 VARCHAR(25) DEFAULT 'XYZ';
             DECLARE CONTINUE HANDLER FOR SQLSTATE '42000'
                 SET po2 = "Table does not exist in L2';
             INSERT INTO tDummy (i, var1);
      -- Table does not exist.
         END L2;
     END L1;
END;