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 诊断区域”。
condition_value
语句中的
表示SIGNAL
要返回的错误值。它可以是一个
SQLSTATE
值(一个 5 个字符的字符串文字)或一个condition_name
引用先前定义的命名条件的
值DECLARE ...
CONDITION
(请参阅第 13.6.7.1 节,“DECLARE ... CONDITION 语句”)。
值可以SQLSTATE
指示错误、警告或“未找到。”值的前两个字符表示其错误类别,如信号条件信息项中所述。某些信号值会导致语句终止;请参阅
信号对处理程序、游标和语句的影响。
语句的SQLSTATE
值
SIGNAL
不应以 开头,'00'
因为这样的值表示成功并且对于发出错误信号无效。无论SQLSTATE
值是直接在
SIGNAL
语句中指定还是在语句中引用的命名条件中指定,都是如此。如果该值无效,Bad SQLSTATE
则会发生错误。
要发出通用SQLSTATE
值的信号,请使用
'45000'
,这意味着“未处理的用户定义的异常。”
该SIGNAL
语句可选地包含一个SET
子句,该子句包含多个信号项,在
condition_information_item_name
=
simple_value_specification
赋值列表中,以逗号分隔。
每个
condition_information_item_name
只能在SET
子句中指定一次。否则,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,则p()
发出警告信号,因为SQLSTATE
以 开头的值是'01'
警告类中的信号。警告不会终止程序,并且可以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
语句的某个范围内声明,并且必须使用
SQLSTATE
值而不是 MySQL 错误号来定义。例子:
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
引用用 MySQL 错误号而不是SQLSTATE
值
定义的命名条件,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,则执行第二
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
)语句中设置的诊断区域条件信息项的名称。所有项目都是标准 SQL,除了MYSQL_ERRNO
,它是 MySQL 扩展。有关这些项目的更多信息,请参阅第 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。
在语句
中分配NULL
给条件信息项是非法的。SIGNAL
A SIGNAL
statement always
specifies an SQLSTATE
value, either
directly, or indirectly by referring to a named condition
defined with an SQLSTATE
value. The first
two characters of an SQLSTATE
value are its
class, and the class determines the default value for the
condition information items:
Class =
'00'
(success)Illegal.
SQLSTATE
values that begin with'00'
indicate success and are not valid forSIGNAL
.Class =
'01'
(warning)MESSAGE_TEXT = 'Unhandled user-defined warning condition'; MYSQL_ERRNO = ER_SIGNAL_WARN
Class =
'02'
(not found)MESSAGE_TEXT = 'Unhandled user-defined not found condition'; MYSQL_ERRNO = ER_SIGNAL_NOT_FOUND
Class >
'02'
(exception)MESSAGE_TEXT = 'Unhandled user-defined exception condition'; MYSQL_ERRNO = ER_SIGNAL_EXCEPTION
For legal classes, the other condition information items are set as follows:
CLASS_ORIGIN = SUBCLASS_ORIGIN = '';
CONSTRAINT_CATALOG = CONSTRAINT_SCHEMA = CONSTRAINT_NAME = '';
CATALOG_NAME = SCHEMA_NAME = TABLE_NAME = COLUMN_NAME = '';
CURSOR_NAME = '';
The error values that are accessible after
SIGNAL
executes are the
SQLSTATE
value raised by the
SIGNAL
statement and the
MESSAGE_TEXT
and
MYSQL_ERRNO
items. These values are
available from the C API:
mysql_sqlstate()
returns theSQLSTATE
value.mysql_errno()
returns theMYSQL_ERRNO
value.mysql_error()
returns theMESSAGE_TEXT
value.
At the SQL level, the output from SHOW
WARNINGS
and SHOW
ERRORS
indicates the MYSQL_ERRNO
and MESSAGE_TEXT
values in the
Code
and Message
columns.
To retrieve information from the diagnostics area, use the
GET DIAGNOSTICS
statement (see
Section 13.6.7.3, “GET DIAGNOSTICS Statement”). For information about the
diagnostics area, see Section 13.6.7.7, “The MySQL Diagnostics Area”.
Signals have different effects on statement execution
depending on the signal class. The class determines how severe
an error is. MySQL ignores the value of the
sql_mode
system variable; in
particular, strict SQL mode does not matter. MySQL also
ignores IGNORE
: The intent of
SIGNAL
is to raise a
user-generated error explicitly, so a signal is never ignored.
In the following descriptions, “unhandled” means
that no handler for the signaled SQLSTATE
value has been defined with
DECLARE ...
HANDLER
.
Class =
'00'
(success)Illegal.
SQLSTATE
values that begin with'00'
indicate success and are not valid forSIGNAL
.Class =
'01'
(warning)The value of the
warning_count
system variable goes up.SHOW WARNINGS
shows the signal.SQLWARNING
handlers catch the signal.Warnings cannot be returned from stored functions because the
RETURN
statement that causes the function to return clears the diagnostic area. The statement thus clears any warnings that may have been present there (and resetswarning_count
to 0).Class =
'02'
(not found)NOT FOUND
handlers catch the signal. There is no effect on cursors. If the signal is unhandled in a stored function, statements end.Class >
'02'
(exception)SQLEXCEPTION
handlers catch the signal. If the signal is unhandled in a stored function, statements end.Class =
'40'
视为普通异常。