目的
SIGNALは、診断域内で例外条件、完了条件(成功条件以外)、またはユーザー定義条件を明示的に発生させます。
呼び出し
実行可能形式。
ストアド プロシージャのみ。
構文
説明
- condition_name
- SQLストアド プロシージャ内で条件を識別するため宣言された変数名。
- SQLSTATE [VALUE] SQLSTATE_code
- 条件域のRETURNED_SQLSTATEに割り当てられるSQLSTATEの値。
- value
- 指定した条件情報名に割当てるテキストまたは数値。
- condition_information_item
- 診断域の条件域から得られる、次のテーブルに示されているフィールド名の1つ。
- CLASS_ORIGIN
- RETURNED_SQLSTATEのクラス値を定義した命名権者の識別。
- CONDITION_IDENTIFIER
- SIGNAL文またはRESIGNAL文で指定された条件名。
- CONDITION_NUMBER
- 1から16までの値を取ります。16は、診断域に格納できる条件の最大数です。
- MESSAGE_LENGTH
- MESSAGE_TEXTの長さ(文字数)。
- MESSAGE_TEXT
- この前のSQL文の実行で返されたエラー メッセージまたは警告メッセージのテキスト、またはSIGNAL文またはRESIGNAL文でシグナル情報として指定されたメッセージ。
- RETURNED_SQLSTATE
- この前のSQL文から返されたSQLSTATE値、SIGNAL文またはRESIGNAL文で指定されたSQLSTATE値、または、SIGNAL文またはRESIGNAL文で条件名が指定されている場合の条件名に関連付けられたSQLSTATE値。
- SUBCLASS_ORIGIN
- RETURNED_SQLSTATEのサブクラス値を定義した命名権者の識別。
使用上の注意
SIGNAL文が実行されると、診断域が空になり、ステートメント(文)域にはSIGNAL文の詳細が入力され、SQLSTATE値またはSIGNAL文で指定された条件名に対応する診断域に、条件番号1の条件域が追加されます。シグナル情報がSIGNAL文で指定されている場合は、シグナル情報で与えられる詳細情報を使って、この追加された条件域が更新されます。
ルール
- SIGNAL文で条件名が指定されている場合、そのSIGNAL文に適用される有効範囲の中で、その条件名を宣言する必要があります。宣言しない場合、ストアド プロシージャのコンパイル中にエラーSPL1079が報告されます。
- SIGNAL文での条件名の使用法は、その条件名が対応するSQLSTATE値の使用法と同じです。 ただし、条件名がSQLSTATE値とともに宣言された場合に限られます。
- SIGNAL文が例外条件またはユーザー定義条件を指定し、その条件を処理する複合文内にハンドラーの定義がない場合、診断域と条件処理のルールは、“RESIGNAL”および“BEGIN ... END”で示したものと同じです。
- SIGNAL文で完了条件を指定し、その条件を処理する複合文内にハンドラーの定義がない場合、条件処理のルールは、“BEGIN ... END”で示したものと同じです。
- ハンドラーでない複合文内のSIGNAL文でユーザー定義条件を指定し、その条件を処理するハンドラーの定義がその複合文内、あるいはSIGNAL文の外側にある複合文にない場合、Teradata Databaseはプロシージャのコンパイル中に警告メッセージを返します。その後、実行時には、SIGNAL文でSQLCODE 7603とSQLSTATE '45000'の例外が発生します。
- 同じ条件名で複数の条件宣言が指定されている場合、SIGNAL文を含む複合文の有効範囲が最も狭い条件宣言が使用されます。
- シグナル情報指定の左側は、次のステートメント(文)域フィールド名のみを明記できます。
- 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による指定条件:
データ型: 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つ。
データ型: CHARACTER(5) CHARACTER SET LATIN |
CLASS_ORIGIN | SIGNALによる指定条件:
データ型: 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文を参照してください。
- シグナル情報指定の条件情報項目で指定した値のデータ型については、診断域の構造を参照してください。