16.20 - SIGNAL - 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

目的

SIGNALは、診断域内で例外条件、完了条件(成功条件以外)、またはユーザー定義条件を明示的に発生させます。

呼び出し

実行可能形式。

ストアド プロシージャのみ。

構文



説明

condition_name
SQLストアド プロシージャ内で条件を識別するため宣言された変数名。
condition_nameが、SQLSTATE値に対応する条件を指定すると、そのSQLSTATEの値は条件域のRETURNED_SQLSTATEに割当てられます。
SQLSTATE [VALUE] SQLSTATE_code
条件域のRETURNED_SQLSTATEに割り当てられるSQLSTATEの値。
value
指定した条件情報名に割当てるテキストまたは数値。
condition_information_item
診断域の条件域から得られる、次のテーブルに示されているフィールド名の1つ。
CLASS_ORIGIN
RETURNED_SQLSTATEのクラス値を定義した命名権者の識別。
値は、クラス値がANSI/ISO SQL:2011規格で定義されている場合はISO 9075、クラス値がSQL:2011規格に対するTeradataのクラス拡張の場合はTeradataとする必要があります。
データ型: VARCHAR(128) CHARACTER SET UNICODE
デフォルト: NULL
CONDITION_IDENTIFIER
SIGNAL文またはRESIGNAL文で指定された条件名。
データ型: VARCHAR(128) CHARACTER SET UNICODE
デフォルト: NULL
CONDITION_NUMBER
1から16までの値を取ります。16は、診断域に格納できる条件の最大数です。
データ型: INTEGER
デフォルト: 0
MESSAGE_LENGTH
MESSAGE_TEXTの長さ(文字数)。
データ型: INTEGER
デフォルト: 0
MESSAGE_TEXT
この前のSQL文の実行で返されたエラー メッセージまたは警告メッセージのテキスト、またはSIGNAL文またはRESIGNAL文でシグナル情報として指定されたメッセージ。
データ型: VARCHAR(128) CHARACTER SET UNICODE
デフォルト: NULL
RETURNED_SQLSTATE
この前のSQL文から返されたSQLSTATE値、SIGNAL文またはRESIGNAL文で指定されたSQLSTATE値、または、SIGNAL文またはRESIGNAL文で条件名が指定されている場合の条件名に関連付けられたSQLSTATE値。
データ型: CHARACTER(5) CHARACTER SET LATIN
デフォルト: NULL
SUBCLASS_ORIGIN
RETURNED_SQLSTATEのサブクラス値を定義した命名権者の識別。
値は、クラス値がANSI/ISO SQL:2011規格で定義されている場合はISO 9075、クラス値がSQL:2011規格に対するTeradataのサブクラス拡張の場合はTeradataとする必要があります。
データ型: VARCHAR(128) CHARACTER SET UNICODE
デフォルト: NULL

使用上の注意

SIGNAL文が実行されると、診断域が空になり、ステートメント(文)域にはSIGNAL文の詳細が入力され、SQLSTATE値またはSIGNAL文で指定された条件名に対応する診断域に、条件番号1の条件域が追加されます。シグナル情報がSIGNAL文で指定されている場合は、シグナル情報で与えられる詳細情報を使って、この追加された条件域が更新されます。

ルール

次のルールが、SIGNAL文に適用されます。
  • SIGNAL文で条件名が指定されている場合、そのSIGNAL文に適用される有効範囲の中で、その条件名を宣言する必要があります。宣言しない場合、ストアド プロシージャのコンパイル中にエラーSPL1079が報告されます。
  • SIGNAL文での条件名の使用法は、その条件名が対応するSQLSTATE値の使用法と同じです。 ただし、条件名がSQLSTATE値とともに宣言された場合に限られます。
  • SIGNAL文が例外条件またはユーザー定義条件を指定し、その条件を処理する複合文内にハンドラーの定義がない場合、診断域と条件処理のルールは、“RESIGNAL”および“BEGIN ... END”で示したものと同じです。
  • SIGNAL文で完了条件を指定し、その条件を処理する複合文内にハンドラーの定義がない場合、条件処理のルールは、“BEGIN ... END”で示したものと同じです。
  • ハンドラーでない複合文内のSIGNAL文でユーザー定義条件を指定し、その条件を処理するハンドラーの定義がその複合文内、あるいはSIGNAL文の外側にある複合文にない場合、Teradata Databaseはプロシージャのコンパイル中に警告メッセージを返します。その後、実行時には、SIGNAL文でSQLCODE 7603とSQLSTATE '45000'の例外が発生します。
  • 同じ条件名で複数の条件宣言が指定されている場合、SIGNAL文を含む複合文の有効範囲が最も狭い条件宣言が使用されます。
signal_informationには、次のルールが適用されます。
  • シグナル情報指定の左側は、次のステートメント(文)域フィールド名のみを明記できます。
    • CLASS_ORIGIN
    • MESSAGE_TEXT
    • SUBCLASS_ORIGIN

      ローカル変数、パラメータ、またはFORループの別名 / 列が指定されると、Teradata Databaseはコンパイル中にリクエストをアボートし、リクエスト側にエラーを返します。

  • シグナル情報指定の左側は、次のステートメント(文)域フィールド名は指定できません。
    • CONDITION_IDENTIFIER
    • CONDITION_NUMBER
    • MESSAGE_LENGTH
    • RETURNED_SQLSTATE

      このうちのいずれかを指定すると、Teradata Databaseはコンパイル中にリクエストをアボートし、リクエスト側にエラーを返します。

  • シグナル情報の左側は、SIGNAL文内に条件名が指定され、指定された条件名がどのSQLSTATE値にも関連付けられていない場合に、次のステートメント(文)域フィールドのみを指定できます。
    • CLASS_ORIGIN
    • SUBCLASS_ORIGIN

      それ以外の場合、Teradata Databaseはコンパイル中にリクエストをアボートし、リクエスト側にエラーを返します。

  • シグナル情報指定では、条件情報項目名を繰り返すことはできません。

    それ以外の場合、Teradata Databaseはコンパイル中にリクエストをアボートし、リクエスト側にエラーを返します。

  • シグナル情報指定の条件情報項目で指定した値のデータ型には、条件域の各列に対して指定したデータ型との互換性が必要です。それ以外の場合、Teradata Databaseはコンパイル中にリクエストをアボートし、リクエスト側にエラーを返します。
  • CLASS_ORIGINまたはSUBCLASS_ORIGINに対しては、シグナル情報変数にISO 9075またはTeradataのどちらも指定できません。

    CLASS_ORIGINまたはSUBCLASS_ORIGINに対してシグナル情報句の右側をISO 9075またはTeradataのどちらかとして指定する場合は、Teradata Databaseはコンパイル中にリクエストをアボートし、リクエスト側にエラーを返します。

    ランタイムにCLASS_ORIGINまたはSUBCLASS_ORIGINに対するシグナル情報句の右側がISO 9075またはTeradataのいずれかになると、Teradata Databaseではリクエストをアボートしてリクエスト側にエラーを返し、SQLCODEを7609に、SQLSTATEを‘T7609’に設定します。

ステートメント(文)域の内容

以下の表に、SIGNAL文実行後のステートメント(文)域の内容を指定します。

フィールド名 内容
COMMAND_FUNCTION SIGNAL
COMMAND_FUNCTION_CODE 92
NUMBER 1
MORE N
ROW_COUNT 0
TRANSCATION_ACTIVE トランザクションがアクティブでない場合、TRANSACTION_ACTIVEには0が入ります

トランザクションがアクティブな場合、TRANSACTION_ACTIVEには1が入ります

条件域1の内容

以下の表に、SIGNAL文実行後の条件域1の内容を指定します。

フィールド名 内容
CLASS_ORIGIN SIGNALによる指定条件:
  • SQLSTATE値、またはSQLSTATE値に関連付けられた条件名で、クラス値がANSI/ISO SQL規格で定義されている場合、CLASS_ORIGINにはISO 9075が入り、クラス値がANSI/ISO SQL規格に対するTeradataの拡張機能の場合、Teradataが入ります。
  • ユーザー定義条件のCLASS_ORIGINには、signal_information変数で指定された値が入ります。
  • 上記のいずれにも当てはまらない場合、CLASS_ORIGINにはNULLが入ります。

データ型: VARCHAR(128) CHARACTER SET UNICODE

CLASS_ORIGIN SIGNALによってSQLSTATE値、またはSQLSTATE値に関連付けられた条件名が指定される場合、CLASS_ORGINはANSI/ISO SQL標準またはTeradata(クラス値がANSI/ISO SQL規格に対するTeradataの拡張機能の場合)で定義されます。

SIGNALによってユーザー定義条件が指定される場合、CLASS_ORIGINには、signal_information変数で指定された値が入ります。

SIGNALの指定内容が上記のいずれでもない場合、CLASS_ORIGINにはNULLが入ります。

データ型: VARCHAR(128) CHARACTER SET UNICODE

CONDITION_IDENTIFIER SIGNAL文で指定された条件名。

SIGNALに条件名が指定されていない場合、このフィールドはNULLに設定されます。

データ型: VARCHAR(128) CHARACTER SET UNICODE

CONDITION_NUMBER 1

データ型: INTEGER

MESSAGE_TEXT SIGNAL文のsignal_information変数で指定したMESSAGE_TEXTの値。

SIGNALにメッセージ テキスト値が指定されていない場合は、このフィールドはNULLに設定されます。

データ型: VARCHAR(128) CHARACTER SET UNICODE

MESSAGE_LENGTH MESSAGE_TEXTの長さ(文字数)。

SIGNALにメッセージ テキスト値が指定されていない場合、このフィールドは0に設定されます。

データ型: INTEGER

RETURNED_SQLSTATE 以下のうちの1つ。
  • SIGNAL文で指定された条件に関連付けられたSQLSTATE値。
  • SIGNAL文で指定されたSQLSTATE値。
  • NULL。

    SIGNAL文で条件名が指定され、どのSQLSTATE値にも関連付けられていない場合、この値はNULLです。

データ型: CHARACTER(5) CHARACTER SET LATIN

CLASS_ORIGIN SIGNALによる指定条件:
  • SQLSTATE値、またはSQLSTATE値に関連付けられた条件名で、クラス値がANSI/ISO SQL規格で定義されている場合、CLASS_ORIGINにはISO 9075が入り、クラス値がANSI/ISO SQL規格に対するTeradataの拡張機能の場合、Teradataが入ります。
  • ユーザー定義条件のCLASS_ORIGINには、signal_information変数で指定された値が入ります。
  • 上記のいずれにも当てはまらない場合、CLASS_ORIGINにはNULLが入ります。

データ型: VARCHAR(128) CHARACTER SET UNICODE

SUBCLASS_ORIGIN SIGNALによってSQLSTATE値、またはSQLSTATE値に関連付けられた条件名が指定される場合、クラス値がANSI/ISO SQL標準で定義されている場合、SUBCLASS_ORIGINにはISO 9075が入り、クラス値がANSI/ISO SQL標準に対するTeradataの拡張機能の場合、Teradataが入ります。

SIGNALによってユーザー定義条件が指定される場合、SUB_CLASSには、signal_information変数で指定された値が入ります。

SIGNALの指定内容が上記のいずれでもない場合、SUB_CLASSにはNULLが入ります。

データ型: VARCHAR(128) CHARACTER ST UNICODE

例: SIGNAL文とハンドラー宣言での条件の使用

次の例は、SIGNAL文での条件名とその条件名に関連付けられたSQLSTATE値に対して定義されたハンドラー宣言の使用法を示しています。

Req1からのストアド プロシージャの実行中、InParam2の値はゼロでSIGNAL文が実行されます。

SIGNAL文は、SQLSTATE '22012'を処理するよう定義されたEXITハンドラーを呼び出します。条件名divide_by_zeroはSQLSTATE '22012'に関連付けられていることに注意してください。

SIGNAL文はdivide_by_zeroを使用し、ハンドラはdivide_by_zeroに関連付けられているSQLSTATE値を処理するよう定義されていますが、 SQLSTATE '22012'のハンドラーが呼び出されます。

ハンドラー アクション文が正常に実行された後、制御は複合文cs1にあり、ストアド プロシージャは終了します。

CREATE PROCEDURE signalsp3 (IN  InParam1 INTEGER,
                            IN  InParam2 INTEGER,
                            OUT OParam3  INTEGER)
 cs1:BEGIN
     DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
     DECLARE EXIT HANDLER FOR SQLSTATE '22012'
         SET OParam3 = 0;
     IF (InParam2 = 0) THEN
         SIGNAL divide_by_zero;
     ELSE
         SET OParam3 = InParam1 + InParam2;
         ...
     END IF;
     ...
 END cs1;
BTEQ> CALL signalsp3(10, 0, OParam3);

例: SIGNAL文での条件名の使用

次の例は、SIGNAL文内での条件名の使用法を示しています。

Req1からのストアド プロシージャの実行中、InParam2の値はゼロでSIGNAL文が実行されます。

SIGNAL文はdivide_by_zeroまたはそれに関連付けられているSQLSTATE '22012'に対して定義されているハンドラーを探します。

divide_by_zeroを処理するようEXITハンドラーが定義されているので、それが呼び出されます。

ハンドラー アクション文が正常に実行された後、制御は複合文cs1にあり、ストアド プロシージャは終了します。

CREATE PROCEDURE signalsp4 (IN  InParam1 INTEGER,
                            IN  InParam2 INTEGER,
                            OUT OParam3  INTEGER)
cs1:BEGIN
    DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
    DECLARE EXIT HANDLER FOR divide_by_zero
        SET OParam3 = 0;
    IF (InParam2 = 0) THEN
        SIGNAL divide_by_zero;
    ELSE
        SET OParam3 = InParam1 + InParam2;
        ...
    END IF;
    ...
END cs1;
BTEQ> CALL signalsp4(10, 0, OParam3);

例: SIGNAL文で発生するCONTINUEハンドラーと例外

以下の例では、SIGNAL文の外側にある複合文で定義されているCONTINUEハンドラーがSIGNAL文で発生した例外を処理します。

ストアド プロシージャの実行中、SIGNAL文はdivide_by_zeroを発生させます。

divide_by_zeroにはcs2を処理するよう定義されたハンドラーがないので、divide_by_zeroに関連付けられたSQLSTATE値は、外側の複合文cs1に伝搬され、cs1のCONTINUEハンドラーによって処理されます。

ハンドラー アクション文が正常に完了した後、制御はSIGNAL divide_by_zeroの次の行に戻ります。

CREATE PROCEDURE signalsp5 (IN  InParam1 INTEGER,
                            IN  InParam2 INTEGER,
                            OUT OParam3  INTEGER)
cs1: BEGIN
     DECLARE CONTINUE HANDLER FOR SQLSTATE '22012'
         SET OParam3=1;
     DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012'
     cs2: BEGIN
         IF (InParam2 = 0) THEN
             SIGNAL divide_by_zero;
             …
         ELSE
             SET OParam3 = InParam1 + InParam2;
             …
         END IF;
         …
     END cs2;
     …
END cs1;
BTEQ> CALL signalsp5(10, 0, OParam3);

例: SIGNAL文でのシグナル情報の使用

次の例は、SIGNAL文内でのシグナル情報の使用法を示しています。

ストアド プロシージャの実行中、SIGNAL文はMESSAGE_TEXTに'balance is too low'を、CLASS_ORIGINに'ストアド プロシージャ'を設定します。

MESSAGE_LENGTHは、暗黙的に19に設定されます。

EXITハンドラーが条件を処理します。

GET DIAGNOSTICS文は、MESSAGE_TEXTとCLASS_ORIGINを最初の条件域から取得し、それらを出力パラメータMessageクラスに割当てます。

EXITハンドラー アクション文が正常に実行された後、制御は複合文cs1にあり、ストアド プロシージャは終了します。

CREATE PROCEDURE setsignalsp1 (INOUT acno    INTEGER,
                               INOUT amt     FLOAT,
                               OUT   Message VARCHAR(50),
                               OUT   Class   VARCHAR(50))
cs1: BEGIN
     DECLARE balance_too_low CONDITION;
     DECLARE count INTEGER DEFAULT 0;
     DECLARE bal_amt, balance FLOAT;
     DECLARE EXIT HANDLER FOR balance_too_low
     BEGIN
         GET DIAGNOSTICS EXCEPTION 1
            Message = MESSAGE_TEXT, Class = CLASS_ORIGIN;
         SET count = count + 1;
         INSERT INTO errortbl VALUES (acno, count, User,
                     current_timestamp, 'Balance too low for the
                                         account');
     END;
     SELECT balamt INTO balance
     FROM Deposit
     WHERE accountno = acno;
     SET bal_amt = balance - amt;
     IF  (bal_amt < 1000) THEN
          SIGNAL balance_too_low
                 SET MESSAGE_TEXT = 'Balance is too low',
                     CLASS_ORIGIN = 'Stored Procedure';
     ELSE
         UPDATE Deposit
         SET balance = bal_amt
         WHERE accountno = acno;
     END IF;
END cs1;

例: 条件宣言とSIGNAL文

以下の例では、SIGNAL文を含む複合文の有効範囲が最も狭い条件宣言が使用されます。

ストアド プロシージャの実行中、InParam2の値はゼロで、複合文cs2内のSIGNAL文でユーザー定義条件divide_by_zeroが発生します。

複合文cs2には、この条件のハンドラーがあるので、それが呼び出されます。複合文cs1には、divide_by_zeroを処理するよう定義されたハンドラーがありますが、条件宣言はSIGNAL文を含んでいる複合文の有効範囲の方が狭いので呼び出されません。

ストアド プロシージャの実行は、ハンドラー アクション文の実行後も続きます。

CREATE PROCEDURE signalsp7 (IN  InParam1 INTEGER,
                            IN  InParam2 INTEGER,
                            OUT OParam3  INTEGER)
cs1: BEGIN
     DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
     DECLARE EXIT HANDLER FOR divide_by_zero
         SET OParam3 = 0;
     cs2: BEGIN
         DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
         DECLARE EXIT HANDLER FOR divide_by_zero
             SET OParam3 = 10;
         IF (InParam2 = 0) THEN
             SIGNAL divide_by_zero;
         ELSE
             SET OParam3 = InParam1 + InParam2;
             …
         END IF;
         …
     END cs2;
     …
END cs1;
BTEQ> CALL signalsp7 (10, 0, OParam3);

関連トピック

以下に関する詳細な情報
  • condition_nameについては、DECLARE CONDITIONを参照してください。
  • SQLSTATEコードとその意味については、SQLSTATEのマッピングを参照してください。
  • 診断域については、診断域を参照してください。
  • 条件名はSIGNAL文で指定され、そのSIGNAL文に適用される有効範囲の中で、条件名を宣言する必要があります。例: SIGNAL文での条件名の使用を参照してください。
  • SIGNAL文での条件名は、その条件名が対応するSQLSTATE値の使用法と同じです。例: SIGNAL文とハンドラー宣言での条件の使用を参照してください。
  • 診断域と条件処理のルールについては、RESIGNALおよびBEGIN … ENDを参照してください。SIGNAL文で完了条件を指定し、その条件を処理する複合文内にハンドラーの定義がない場合については、BEGIN … ENDを参照してください。
  • 複数の条件宣言が同一の条件名に指定されている場合は、例: 条件宣言とSIGNAL文を参照してください。
  • シグナル情報指定の条件情報項目で指定した値のデータ型については、診断域の構造を参照してください。