17.00 - 17.05 - SIGNALおよびRESIGNAL文の特別な条件処理 - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLデータ定義言語 詳細トピック

Product
Advanced SQL Engine
Teradata Database
Release Number
17.00
17.05
Release Date
2020年6月
Content Type
プログラミング リファレンス
Publication ID
B035-1184-170K-JPN
Language
日本語 (日本)
条件宣言で定義した条件名は、次に示す2つの目的のために条件ハンドラー宣言に指定できます。
  • 特定のSQLSTATE値に説明的なシンボリック名を関連付けられるようにして、プログラムを文書化するため。
  • ユーザー定義条件を指定できるようにし、SIGNALまたはRESIGNAL文でプロシージャが条件名を使用するときに、条件ハンドラーがユーザー定義条件に基づいた処理を実行できるようにするため。
ハンドラー宣言の条件名の指定には、次の使用上のルールが適用されます。
  • ハンドラー宣言で指定した条件名は、それを含む複合文内か、それを含む外側の複合文内のどちらかで宣言されている必要があります。

    次の例は、ハンドラー内での条件名とそれに関連付けられたSQLSTATE値を指定する方法を示しています。この例では、3行目の条件宣言で条件名divide_by_zeroをSQLSTATE '22012'に関連付けて定義しています。4行目では、divide_by_zeroを処理するEXITハンドラを定義しています。プロシージャの実行中、ゼロ除算の例外SQLSTATE '22012'が8行目で発生し、divide_by_zeroのEXITハンドラがそれを処理します。EXITハンドラ文が正常に完了すると、複合文cs1にプロシージャの制御が移り、正常に完了します。

    1.   CREATE PROCEDURE condsp1 (
           INOUT IOParam2 INTEGER,
           OUT   OParam3  INTEGER)
    2.   cs1: BEGIN
    3.       DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012'; 
    4.       DECLARE EXIT HANDLER 
    5.           FOR divide_by_zero, SQLSTATE '42000' 
    6.               SET OParam3 = 0; 
    7.       SET IOParam2=0;
    8.       SET OParam3 = 20/IOParam2; /* raises exception 22012 */ 
    9.   END cs1;
  • ハンドラー宣言内で条件値にSQLEXCEPTION、SQLWARNINGまたはNOT FOUNDを指定すると、同じハンドラー宣言内でさらに条件名を指定することはできなくなります。指定した場合、プロシージャはアボートし、コンパイル中にリクエスト側にエラーを返します。

    次の例では、条件名と汎用条件を別々のハンドラーで指定する方法を示します。この例では、4行目でSQLEXCEPTIONのためにハンドラが定義され、7行目で条件名divide_by_zeroのために別のハンドラが定義されています。

    1.   CREATE PROCEDURE condsp1 (
           OUT OParam3 INTEGER)
    2.   cs1: BEGIN
    3.       DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
    4.       DECLARE EXIT HANDLER 
    5.           FOR SQLEXCEPTION 
    6.               SET OParam3 = 0;
    7.       DECLARE EXIT HANDLER 
    8.           FOR divide_by_zero 
    9.               SET OParam3 = 1;
    10.   …
    11.  END cs1;
         DROP TABLE notab;
         CALL condsp1(IOParam2, OParam3);

    次の例では、条件名と汎用条件の同一ハンドラー内での以外の有効な指定を示しています。この例では、5行目でSQLEXCEPTIONと条件名divide_by_zeroの両方を指定しているハンドラがありますが、これは無効です。この方法で定義されたプロシージャはアボートし、コンパイル中にリクエスト側にエラーを返します。

    1.   CREATE PROCEDURE condsp2 (
           OUT OParam3 INTEGER)
    2.   cs1: BEGIN
    3.       DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
    4.       DECLARE EXIT HANDLER 
    5.           FOR SQLEXCEPTION, divide_by_zero 
    6.               SET OParam3 = 0; 
    7.    …
    8.   END cs1;
  • ハンドラー宣言内で、同一の条件名を複数回指定することはできません。この方法で定義されたプロシージャはアボートし、コンパイル中にリクエスト側にエラーを返します。

    次の例では、同一のハンドラー内で同一の条件名が2回繰り返される無効な指定を示しています。この例では、5行目のハンドラー内で条件名divide_by_zeroが複数指定されています。

    1.   CREATE PROCEDURE condsp2 (
           OUT OParam3 INTEGER)
    2.   cs1: BEGIN
    3.       DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
    4.       DECLARE EXIT HANDLER 
    5.           FOR divide_by_zero, divide_by_zero 
    6.               SET OParam3 = 0; 
    7.    …
    8.   END cs1;
  • 1つのハンドラー宣言で、条件名と、その条件名に関連付けたSQLSTATEの両方を指定することはできません。この方法で定義されたプロシージャはアボートし、コンパイル中にリクエスト側にエラーを返します。

    次の例では、同一ハンドラ内に条件名と、それに関連付けたSQLSTATE値がある無効な指定を示しています。この例では、4行目のハンドラーが条件名divide_by_zeroと、その条件名に関連付けたSQLSTATE値'22012'の両方を処理するように定義されています。

    1.   CREATE PROCEDURE condsp2 (
           OUT OParam3 INTEGER)
    2.   cs1: BEGIN
    3.       DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
    4.       DECLARE EXIT HANDLER 
    5.           FOR divide_by_zero, SQLSTATE '22012' 
    6.               SET OParam3 = 0; 
    7.    …
    8.   END cs1;
  • あるハンドラー宣言が条件名を処理するように定義されている場合、その条件名に関連付けたSQLSTATEを同じ複合文内の別のハンドラー宣言で定義することはできません。この方法で定義されたプロシージャはアボートし、コンパイル中にリクエスト側にエラーを返します。

    次の例では、条件名と、それに関連付けたSQLSTATE値が別々のハンドラーにある無効な指定を示しています。この例では、4行目のハンドラーでdivide_by_zeroを処理する定義が行なわれ、7行目のハンドラでSQLSTATE '22012' (divide_by_zeroに関連付けたSQLSTATE値)の定義が行なわれています。

    1.   CREATE PROCEDURE condsp2 (
           OUT OParam3 INTEGER)
    2.   cs1: BEGIN
    3.       DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
    4.       DECLARE EXIT HANDLER 
    5.           FOR divide_by_zero 
    6.               SET OParam3 = 0; 
    7.       DECLARE EXIT HANDLER 
    8.           FOR SQLSTATE '22012' 
    9.               SET OParam3 = 1; 
    10.   …
    11.  END cs1;
  • 同一の複合文内で、同じ条件名を持つ複数のハンドラー宣言を指定することはできません。この方法で定義されたプロシージャはアボートし、コンパイル中にリクエスト側にエラーを返します。

    次の例では、複数のハンドラーに同じ条件名がある無効な指定を示しています。この例では、4行目と7行目のハンドラが同じ条件名divide_by_zeroを処理するために定義されています。

    1.   CREATE PROCEDURE condsp1 (
           OUT OParam3 INTEGER)
    2.   cs1: BEGIN
    3.       DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
    4.       DECLARE EXIT HANDLER 
    5.           FOR divide_by_zero 
    6.               SET OParam3 = 0; 
    7.       DECLARE EXIT HANDLER 
    8.           FOR divide_by_zero 
    9.               SET OParam3 = 1; 
    10.   …
    11.  END cs1;
  • 関連付けたSQLSTATE値がある条件名を処理するハンドラーを宣言すると、このハンドラーにはそのSQLSTATE値も関連付けられます。

    次の例は、ハンドラ内での条件名とそれに関連付けられたSQLSTATE値を指定する方法を示しています。この例では、3行目の条件宣言で条件名divide_by_zeroと、それに関連付けるSQLSTATE '22012'を定義しています。4行目のEXITハンドラは、divide_by_zeroを処理するための定義です。プロシージャの実行中、ゼロ除算の例外SQLSTATE '22012'が8行目で発生し、divide_by_zeroを処理するために定義したEXITハンドラがそれを処理します。EXITハンドラー文が正常に完了すると、複合文cs1にプロシージャの制御が移り、正常に完了します。

    1.   CREATE PROCEDURE condsp1 (
           INOUT IOParam2 INTEGER,
           OUT   OParam3  INTEGER)
    2.   cs1: BEGIN
    3.       DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012'; 
    4.       DECLARE EXIT HANDLER 
    5.           FOR divide_by_zero, SQLSTATE '42000' 
    6.               SET OParam3 = 0; 
    7.       SET IOParam2=0;
    8.       SET OParam3 = 20/IOParam2;     /* raises exception 22012 */
    9.   END cs1;
  • ハンドラー アクションは、ハンドラー宣言の条件の複数値で定義されたすべての条件名に関連付けられます。

    次の例では、同じハハンドラー アクションと複数の条件名との関連付けを示しています。この例では、5行目のCONTINUEハンドラーで条件名divide_by_zeroおよびtable_does_not_existを定義しています。プロシージャの実行中、5行目のCONTINUEハンドラーは、9行目で発生する例外SQLSTATE '22012' (SQLCODE 2802)と、10行目で発生する例外SQLSTATE '42000' (SQLCODE 3807)を処理することになります。

    1.   CREATE PROCEDURE condsp1 (
           INOUT IOParam2 INTEGER,
           OUT   OParam3  CHARACTER(30))
    2.   cs1: BEGIN
    3.       DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
    4.       DECLARE table_does_not_exist CONDITION FOR SQLSTATE '42000';
    5.       DECLARE CONTINUE HANDLER 
    6.           FOR divide_by_zero, table_does_not_exist 
    7.               SET OParam3 = 0; 
    8.       SET IOParam2=0;
    9.       SET OParam3 = 20/IOParam2;         /*raises exception 22012*/
    10.      INSERT notab VALUES (IOParam2+20);/*raises exception 42000*/
    11. END Cs1;
    BTEQ> DROP TABLE notab;
    BTEQ> CALL condsp1(IOParam2, OParam3);