条件ハンドラーのルール - Teradata Database - Teradata Vantage NewSQL Engine

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

Product
Teradata Database
Teradata Vantage NewSQL Engine
Release Number
16.20
Published
2019年3月
Language
日本語
Last Update
2019-10-29
dita:mapPath
ja-JP/rop1530578142648.ditamap
dita:ditavalPath
ja-JP/rop1530578142648.ditaval
dita:id
B035-1148
Product Category
Software
Teradata Vantage
  • 条件ハンドラーは、正常な完了を除く完了条件と例外条件に対して定義できます。正常な完了(SQLSTATE = ‘00000’)に対して条件ハンドラーを定義することはできません。
  • 条件ハンドラーは、複合文の中でのみ宣言できます。

    複合文を含まないストアド プロシージャでは、ハンドラーは宣言できません。

  • DECLARE HANDLER文では、同じSQLSTATコードを繰り返し使用することはできません。
  • 同じ複合文内で、複数の条件ハンドラーに対して同じSQLSTATEコードを宣言することはできません。

    しかし、ストアド プロシージャ内の他の入れ子の、あるいは入れ子ではない複合文の中の条件ハンドラーに対しては、同じSQLSTATEコードを再利用することができます。

  • SQLEXCEPTION、SQLWARNING、NOT FOUND、またはこれらの一般条件の任意の組み合わせをハンドラー宣言内に指定することができます。
  • 複合文の中では、各汎用条件ハンドラーを最高1回ずつ宣言することができます。

    ストアド プロシージャの中の他の複合文で同じ一般条件を再利用することができます。

  • ある1つのSQLSTATE値と1つ以上の一般条件を同一のDECLARE HANDLER文内に宣言することはできません。
  • ハンドラー アクションに複数の文を指定する場合、すべての文はBEGIN…END複合文内に含める必要があります。

    ハンドラー アクションでは、入れ子の複合文を実行できます。

  • 条件ハンドラーの有効範囲は、それが宣言されている複合文(すべての入れ子の複合文を含む)です。
条件名を指定するハンドラーを宣言する場合は、次の追加ルールが適用されます。
  • 条件名が同一でない限り、ハンドラー宣言で1つ以上の条件名を指定できます。ハンドラ アクションは、DECLARE HANDLER文内のすべての条件名に関連付けられます。
  • ハンドラー宣言内で同じ条件名を繰り返すことはできません。そのような指定をすると、ストアド プロシージャのコンパイル中にエラーSPL1052が報告され、そのストアド プロシージャは作成されません。
  • 同じハンドラー宣言内に、条件名と一般条件を指定することはできません。そのような指定をすると、ストアド プロシージャのコンパイル中にエラーSPL1082が報告され、そのストアド プロシージャは作成されません。
  • 同じハンドラー宣言内に、条件名とその条件名に関連付けられたSQLSTATE値を指定することはできません。そのような指定をすると、ストアド プロシージャのコンパイル中にエラーSPL1054が報告され、そのストアド プロシージャは作成されません。
  • 同じ複合文内で同じ条件名を指定するような複数のハンドラーを宣言することはできません。そのような指定をすると、ストアド プロシージャのコンパイル中にエラーSPL1052が報告され、そのストアド プロシージャは作成されません。
  • 条件名に対してハンドラーを宣言すると、同じ複合文内で別のハンドラーを宣言して、その条件名に関連付けられたSQLSTATE値を処理できません。そのような指定をすると、ストアド プロシージャのコンパイル中にエラーSPL1054が報告され、そのストアド プロシージャは作成されません。
  • SQLSTATE値が関連付けられている条件名に対してハンドラーを宣言すると、そのSQLSTATE値を持つ条件の処理にも同じハンドラーが使用されます。

例: ハンドラー内での条件名とそれに関連付けられたSQLSTATE値の使用

次の例は、ハンドラー内での条件名とそれに関連付けられたSQLSTATE値の使用法を示しています。条件宣言では、条件名divide_by_zeroを定義し、それにSQLSTATE '22012'を関連付けています。EXITハンドラーは、divide_by_zeroを処理するよう定義されています。ストアド プロシージャの実行中、SQLSTATE '22012'となるdivide-by-zero例外が発生し、EXITハンドラーがそれを処理します。EXITハンドラー文が正常に完了した後、制御は複合文cs1にあり、ストアド プロシージャは正常に完了します。

CREATE PROCEDURE condsp1 (INOUT IOParam2 INTEGER,
                          OUT OParam3 INTEGER)
cs1: BEGIN
   DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
   DECLARE EXIT HANDLER
      FOR divide_by_zero, SQLSTATE '42000'
         SET OParam3 = 0;
   SET IOParam2 = 0;
   SET OParam3 = 20/IOParam2;    /* raises exception 22012 */
END cs1;

例: ハンドラー アクションと複数の条件名の関連付け

次の例は、同じハンドラー アクションと複数の条件名との関連付けを示しています。条件名divide_by_zerotable_does_not_existに対してCONTINUEハンドラーが定義されています。ストアド プロシージャの実行中、例外ERRAMPEZERODIV (SQLCODE 2802 および SQLSTATE '22012')とERRTEQTVNOEXIST (SQLCODE 3807およびSQLSTATE '42000')の両方をCONTINUEハンドラーで処理できます。

CREATE PROCEDURE condsp2 (INOUT IOParam2 INTEGER,
                          OUT OParam3 CHAR(30))
Cs1: BEGIN
   DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
   DECLARE table_does_not_exist CONDITION FOR SQLSTATE '42000';
   DECLARE CONTINUE HANDLER
      FOR divide_by_zero, table_does_not_exist
         SET OParam3 = 0;
   SET IOParam2=0;
   SET OParam3 = 20/IOParam2;    /* raises exception 22012 */
   INSERT notab VALUES (IOParam2 + 20); /* raises exception 42000 */
END Cs1;
BTEQ> DROP TABLE notab;
BTEQ> CALL condsp2(IOParam2, OParam3);

例: 汎用条件と明示的に宣言された条件のハンドラーの使用

次の例は、一般条件や明示的に宣言された条件を処理するためのさまざまなハンドラーの使用法を示しています。第2の宣言ハンドラーは、divide-by-zero例外を処理します。SQLEXCEPTIONに対して宣言された第1のハンドラは、その他すべての例外条件を処理します。

CREATE PROCEDURE condsp3 (OUT OParam3 INTEGER)
cs1: BEGIN
   DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
   DECLARE EXIT HANDLER
      FOR SQLEXCEPTION
         SET OParam3 = 0;
   DECLARE EXIT HANDLER
      FOR divide_by_zero
         SET OParam3 = 1;
   ...
END cs1;

例: 宣言された条件と汎用条件の両方での同一ハンドラーの使用結果

同じハンドラーを使って、宣言された条件と一般条件の両方を処理することはできません。この例のハンドラーは、SQLEXCEPTIONと条件名divide_by_zeroの両方に対して定義されています。ストアド プロシージャのコンパイル中に、エラーSPL1082が報告され、ストアド プロシージャは作成されません。

CREATE PROCEDURE condsp4 (OUT OParam3 INTEGER)
cs1: BEGIN
   DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
   DECLARE EXIT HANDLER
      FOR SQLEXCEPTION, divide_by_zero
         SET OParam3 = 0;
   ...
END cs1;

例: 処理条件とSQLSTATEの定義

同じハンドラ内に、条件名とその条件名に関連付けられたSQLSTATE値に対するハンドラーを宣言することはできません。この例では、条件名divide_by_zerodivide_by_zeroに関連付けられたSQLSTATE値'22012'を処理するようハンドラーが定義されています。ストアド プロシージャのコンパイル中に、エラーSPL1054が報告され、ストアド プロシージャは作成されません。

CREATE PROCEDURE condsp5 (OUT OParam3 INTEGER)
cs1: BEGIN
   DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
   DECLARE EXIT HANDLER
      FOR divide_by_zero, SQLSTATE '22012'
         SET OParam3 = 0;
   ...
END cs1;

例: 同一条件名で2つのハンドラーを宣言した場合の結果

同じ複合文内で同じ条件名に対して複数のハンドラーを宣言することはできません。この例では、複合文cs1の中で、同じ条件名divide_by_zeroに対して2つのハンドラーが定義されています。ストアド プロシージャのコンパイル中に、エラーSPL1052が報告され、ストアド プロシージャは作成されません。

CREATE PROCEDURE condsp6 (OUT OParam3 INTEGER)
cs1: BEGIN
   DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
   DECLARE EXIT HANDLER
     FOR divide_by_zero
         SET OParam3 = 0;
   DECLARE EXIT HANDLER
      FOR divide_by_zero
         SET OParam3 = 1;
   ...
END cs1;

例: 条件名とSQLSTATE値のハンドラーを宣言した場合の結果

同じ複合文内で、ある条件名に対するハンドラーと、その条件名に関連付けられたSQLSTATE値に対するもう1つ別のハンドラーを宣言することはできません。この例では、最初のハンドラは条件名divide_by_zeroを処理するよう定義されています。第2のハンドラは、divide_by_zeroに関連付けられたSQLSTATE '22012'に対して定義されています。両方のハンドラーが複合文cs1の中に定義されています。そのため、ストアド プロシージャのコンパイル中に、エラーSPL1054が報告され、ストアド プロシージャは作成されません。

CREATE PROCEDURE condsp7 (OUT OParam3 INTEGER)
cs1: BEGIN
   DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
   DECLARE EXIT HANDLER
      FOR divide_by_zero
         SET OParam3 = 0;
   DECLARE EXIT HANDLER
      FOR SQLSTATE '22012'
         SET OParam3 = 1;
   ...
END cs1;

関連トピック

以下に関する詳細な情報