SIGNAL condition_value
[SET signal_information_item
[, signal_information_item] ...]
condition_value: {
SQLSTATE [VALUE] sqlstate_value
| condition_name
}
signal_information_item:
condition_information_item_name = simple_value_specification
condition_information_item_name: {
CLASS_ORIGIN
| SUBCLASS_ORIGIN
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
}
condition_name, simple_value_specification:
(see following discussion)
SIGNAL
は、エラー「を返す」ための方法です。 SIGNAL
は、ハンドラ、アプリケーションの外側の部分、またはクライアントにエラー情報を提供します。 また、エラーの特性 (エラー番号、SQLSTATE
値、メッセージ) に対する制御も提供します。 SIGNAL
を使用しない場合は、存在しないテーブルを意図的に参照してルーチンがエラーを返すようにする、などの回避方法に頼る必要があります。
SIGNAL
ステートメントの実行に必要な権限はありません。
診断領域から情報を取得するには、GET DIAGNOSTICS
ステートメントを使用します (セクション13.6.7.3「GET DIAGNOSTICS ステートメント」を参照してください)。 診断領域については、セクション13.6.7.7「MySQL の診断領域」を参照してください。
SIGNAL
ステートメント内の condition_value
は、返されるエラー値を示します。 これは、SQLSTATE
値 (5 文字の文字列リテラル) か、または以前に DECLARE ... CONDITION
で定義された名前付き条件を参照する condition_name
にすることができます (セクション13.6.7.1「DECLARE ... CONDITION ステートメント」を参照してください)。
SQLSTATE
値は、エラー、警告、または「見つからない」を示す場合があります。 シグナルの条件情報項目で説明されているように、この値の最初の 2 文字はそのエラークラスを示します。 一部のシグナル値はステートメントを終了させます。ハンドラ、カーソル、およびステートメントに対するシグナルの影響を参照してください。
'00'
は成功を示し、エラーの通知には有効でないため、SIGNAL
ステートメントの SQLSTATE
値をこのような値で始めるべきではありません。 これは、SQLSTATE
値が SIGNAL
ステートメントで直接、またはこのステートメントで参照されている名前付き条件のどちらで指定されている場合にも当てはまります。 この値が無効である場合は、Bad SQLSTATE
エラーが発生します。
一般的な SQLSTATE
値を通知するには、'45000'
を使用します。これは、「未処理のユーザー定義の例外」を示します。
SIGNAL
ステートメントには、オプションで、複数のシグナル項目を含む SET
句が condition_information_item_name
= simple_value_specification
割当てのリストにカンマで区切られて含まれます。
各 condition_information_item_name
は、SET
句内で 1 回だけ指定できます。 そうでない場合は、Duplicate condition information item
エラーが発生します。
有効な simple_value_specification
指示子は、ストアドプロシージャーやストアドファンクションのパラメータ、DECLARE
で宣言されたストアドプログラムのローカル変数、ユーザー定義変数、システム変数、またはリテラルを使用して指定できます。 文字リテラルには、_charset
イントロデューサを含めることができます。
許可される condition_information_item_name
値については、シグナルの条件情報項目を参照してください。
次のプロシージャーは、その入力パラメータである pval
の値に応じて、エラーまたは警告を通知します。
CREATE PROCEDURE p (pval INT)
BEGIN
DECLARE specialty CONDITION FOR SQLSTATE '45000';
IF pval = 0 THEN
SIGNAL SQLSTATE '01000';
ELSEIF pval = 1 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'An error occurred';
ELSEIF pval = 2 THEN
SIGNAL specialty
SET MESSAGE_TEXT = 'An error occurred';
ELSE
SIGNAL SQLSTATE '01000'
SET MESSAGE_TEXT = 'A warning occurred', MYSQL_ERRNO = 1000;
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'An error occurred', MYSQL_ERRNO = 1001;
END IF;
END;
pval
が 0 である場合、'01'
で始まる SQLSTATE
値は警告クラス内のシグナルであるため、p()
は警告を通知します。 この警告はプロシージャーを終了させず、そのプロシージャーから戻ったあとに SHOW WARNINGS
で確認できます。
pval
が 1 である場合、p()
はエラーを通知し、MESSAGE_TEXT
条件情報項目を設定します。 このエラーはプロシージャーを終了させ、そのテキストがエラー情報とともに返されます。
pval
が 2 である場合、この場合は名前付き条件を使用して SQLSTATE
値が指定されているにもかかわらず、同じエラーが通知されます。
pval
がその他の任意の値である場合、p()
は最初に警告を通知し、メッセージテキストとエラー番号の条件情報項目を設定します。 この警告はプロシージャーを終了させないため、実行が続行され、そのあと p()
はエラーを通知します。 このエラーはプロシージャーを終了させます。 警告によって設定されたメッセージテキストとエラー番号は、エラーによって設定された値によって置き換えられ、それがエラー情報とともに返されます。
SIGNAL
は通常、ストアドプログラム内で使用されますが、これはハンドラのコンテキストの外部で許可される MySQL 拡張です。 たとえば、mysql クライアントプログラムを呼び出す場合は、プロンプトで次のステートメントのいずれかを入力できます。
SIGNAL SQLSTATE '77777';
CREATE TRIGGER t_bi BEFORE INSERT ON t
FOR EACH ROW SIGNAL SQLSTATE '77777';
CREATE EVENT e ON SCHEDULE EVERY 1 SECOND
DO SIGNAL SQLSTATE '77777';
SIGNAL
は、次のルールに従って実行されます。
SIGNAL
ステートメントが特定の SQLSTATE
値を示している場合、その値は、指定された条件を通知するために使用されます。 例:
CREATE PROCEDURE p (divisor INT)
BEGIN
IF divisor = 0 THEN
SIGNAL SQLSTATE '22012';
END IF;
END;
SIGNAL
ステートメントが名前付き条件を使用している場合、その条件は SIGNAL
ステートメントに適用される何らかのスコープ内で宣言される必要があり、また MySQL エラー番号ではなく SQLSTATE
値を使用して定義される必要があります。 例:
CREATE PROCEDURE p (divisor INT)
BEGIN
DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
IF divisor = 0 THEN
SIGNAL divide_by_zero;
END IF;
END;
その名前付き条件が SIGNAL
ステートメントのスコープ内に存在しない場合は、Undefined CONDITION
エラーが発生します。
SIGNAL
が、SQLSTATE
値ではなく MySQL エラー番号で定義された名前付き条件を参照している場合は、SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE
エラーが発生します。 次のステートメントを発行すると、名前付き条件が MySQL エラー番号に関連付けられているため、そのエラーが発生します。
DECLARE no_such_table CONDITION FOR 1051;
SIGNAL no_such_table;
特定の名前を持つ条件が異なるスコープで複数回宣言されている場合は、もっともローカルなスコープを持つ宣言が適用されます。 次のプロシージャーを考えてみます。
CREATE PROCEDURE p (divisor INT)
BEGIN
DECLARE my_error CONDITION FOR SQLSTATE '45000';
IF divisor = 0 THEN
BEGIN
DECLARE my_error CONDITION FOR SQLSTATE '22012';
SIGNAL my_error;
END;
END IF;
SIGNAL my_error;
END;
divisor
が 0 である場合は、最初の SIGNAL
ステートメントが実行されます。 もっとも内側の my_error
条件宣言が適用され、SQLSTATE
'22012'
が発生します。
divisor
が 0 でない場合は、2 番目の SIGNAL
ステートメントが実行されます。 もっとも外側の my_error
条件宣言が適用され、SQLSTATE
'45000'
が発生します。
条件が発生したときにサーバーがハンドラを選択する方法については、セクション13.6.7.6「ハンドラのスコープに関するルール」を参照してください。
シグナルが例外ハンドラ内で発生する場合があります。
CREATE PROCEDURE p ()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SIGNAL SQLSTATE VALUE '99999'
SET MESSAGE_TEXT = 'An error occurred';
END;
DROP TABLE no_such_table;
END;
CALL p()
が DROP TABLE
ステートメントに達します。 no_such_table
という名前のテーブルが存在しないため、エラーハンドラがアクティブ化されます。 エラーハンドラは元のエラー (「このようなテーブルがない」) を破棄し、SQLSTATE
'99999'
の新しいエラーとメッセージ An error occurred
を作成します。
次の表は、SIGNAL
(または RESIGNAL
) ステートメントで設定できる診断領域条件情報項目の名前を一覧表示しています。 MySQL 拡張である MYSQL_ERRNO
を除き、すべての項目が標準 SQL です。 これらの項目の詳細は、セクション13.6.7.7「MySQL の診断領域」を参照してください。
Item Name Definition
--------- ----------
CLASS_ORIGIN VARCHAR(64)
SUBCLASS_ORIGIN VARCHAR(64)
CONSTRAINT_CATALOG VARCHAR(64)
CONSTRAINT_SCHEMA VARCHAR(64)
CONSTRAINT_NAME VARCHAR(64)
CATALOG_NAME VARCHAR(64)
SCHEMA_NAME VARCHAR(64)
TABLE_NAME VARCHAR(64)
COLUMN_NAME VARCHAR(64)
CURSOR_NAME VARCHAR(64)
MESSAGE_TEXT VARCHAR(128)
MYSQL_ERRNO SMALLINT UNSIGNED
文字項目の文字セットは UTF-8 です。
SIGNAL
ステートメント内で条件情報項目に NULL
を割り当てることはできません。
SIGNAL
ステートメントは直接にか、または SQLSTATE
値で定義された名前付き条件を参照することによって間接的にかにかかわらず、常に SQLSTATE
値を指定します。 SQLSTATE
値の最初の 2 文字はそのクラスであり、このクラスによって、その条件情報項目のデフォルト値が決定されます。
-
クラス =
'00'
(成功)不正です。
'00'
で始まるSQLSTATE
値は成功を示すため、SIGNAL
には有効でありません。 -
クラス =
'01'
(警告)MESSAGE_TEXT = 'Unhandled user-defined warning condition'; MYSQL_ERRNO = ER_SIGNAL_WARN
-
クラス =
'02'
(見つからない)MESSAGE_TEXT = 'Unhandled user-defined not found condition'; MYSQL_ERRNO = ER_SIGNAL_NOT_FOUND
-
クラス >
'02'
(例外)MESSAGE_TEXT = 'Unhandled user-defined exception condition'; MYSQL_ERRNO = ER_SIGNAL_EXCEPTION
正当なクラスの場合は、その他の条件情報項目が次のように設定されます。
CLASS_ORIGIN = SUBCLASS_ORIGIN = '';
CONSTRAINT_CATALOG = CONSTRAINT_SCHEMA = CONSTRAINT_NAME = '';
CATALOG_NAME = SCHEMA_NAME = TABLE_NAME = COLUMN_NAME = '';
CURSOR_NAME = '';
SIGNAL
が実行されたあとにアクセスできるエラー値は、SIGNAL
ステートメントによって発生した SQLSTATE
値と、MESSAGE_TEXT
および MYSQL_ERRNO
項目です。 これらの値は、次の C API から取得できます。
mysql_sqlstate()
は、SQLSTATE
値を返します。mysql_errno()
は、MYSQL_ERRNO
値を返します。mysql_error()
は、MESSAGE_TEXT
値を返します。
SQL レベルでは、SHOW WARNINGS
および SHOW ERRORS
からの出力に、Code
および Message
カラムの MYSQL_ERRNO
および MESSAGE_TEXT
の値が示されます。
診断領域から情報を取得するには、GET DIAGNOSTICS
ステートメントを使用します (セクション13.6.7.3「GET DIAGNOSTICS ステートメント」を参照してください)。 診断領域については、セクション13.6.7.7「MySQL の診断領域」を参照してください。
ステートメントの実行に対するシグナルの影響は、そのシグナルのクラスによって異なります。 このクラスによって、エラーの重大性が決定されます。 MySQL は、sql_mode
システム変数の値を無視します。特に、厳密な SQL モードは問題になりません。 MySQL は IGNORE
も無視します。SIGNAL
の目的はユーザーが生成したエラーを明示的に発生させることであるため、シグナルが無視されることはありません。
次の説明で、「未処理」は、通知された SQLSTATE
値に対するハンドラが DECLARE ... HANDLER
で定義されていないことを示します。
-
クラス =
'00'
(成功)不正です。
'00'
で始まるSQLSTATE
値は成功を示すため、SIGNAL
には有効でありません。 -
クラス =
'01'
(警告)warning_count
システム変数の値が増やされます。SHOW WARNINGS
がシグナルを示します。SQLWARNING
ハンドラがシグナルをキャッチします。ストアドファンクションから警告を返すことはできません。関数を戻す
RETURN
ステートメントによって診断領域がクリアされるためです。 したがって、このステートメントはそこに存在する可能性のある警告をすべてクリアします (さらに、warning_count
を 0 にリセットします)。 -
クラス =
'02'
(見つからない)NOT FOUND
ハンドラがシグナルをキャッチします。 カーソルには影響しません。 ストアドファンクションでシグナルが処理されない場合、ステートメントは終了します。 -
クラス >
'02'
(例外)SQLEXCEPTION
ハンドラがシグナルをキャッチします。 ストアドファンクションでシグナルが処理されない場合、ステートメントは終了します。 -
クラス =
'40'
通常の例外として処理されます。