13.6.7.5 SIGNAL Statement语句

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 is the way to return an error. SIGNAL是“返回”错误的方式。SIGNAL provides error information to a handler, to an outer portion of the application, or to the client. SIGNAL向处理程序、应用程序的外部部分或客户端提供错误信息。Also, it provides control over the error's characteristics (error number, SQLSTATE value, message). 此外,它还提供了对错误特征(错误号、SQLSTATE值、消息)的控制。Without SIGNAL, it is necessary to resort to workarounds such as deliberately referring to a nonexistent table to cause a routine to return an error.在不使用SIGNAL的情况下,有必要采取变通办法,例如故意引用不存在的表,以导致例程返回错误。

No privileges are required to execute the SIGNAL statement.执行SIGNAL语句不需要特权。

To retrieve information from the diagnostics area, use the GET DIAGNOSTICS statement (see Section 13.6.7.3, “GET DIAGNOSTICS Statement”). 要从诊断区域检索信息,请使用GET DIAGNOSTICS语句(参见第13.6.7.3节,“GET DIAGNOSTICS语句”)。For information about the diagnostics area, see Section 13.6.7.7, “The MySQL Diagnostics Area”.有关诊断区域的信息,请参阅第13.6.7.7节,“MySQL诊断区域”

SIGNAL Overview概述

The condition_value in a SIGNAL statement indicates the error value to be returned. SIGNAL语句中的condition_value指示要返回的错误值。It can be an SQLSTATE value (a 5-character string literal) or a condition_name that refers to a named condition previously defined with DECLARE ... CONDITION (see Section 13.6.7.1, “DECLARE ... CONDITION Statement”).它可以是一个SQLSTATE值(一个5个字符的字符串文字),也可以是一个condition_name,它引用了以前用DECLARE ... CONDITION定义的命名条件(见第13.6.7.1节,“DECLARE ... CONDITION语句”)。

An SQLSTATE value can indicate errors, warnings, or not found. SQLSTATE值可以指示错误、警告或“未找到”。The first two characters of the value indicate its error class, as discussed in Signal Condition Information Items. 值的前两个字符表示其错误类别,如信号条件信息项中所述。Some signal values cause statement termination; see Effect of Signals on Handlers, Cursors, and Statements.一些信号值导致语句终止;请参见信号对处理程序、游标和语句的影响

The SQLSTATE value for a SIGNAL statement should not start with '00' because such values indicate success and are not valid for signaling an error. SIGNAL语句的SQLSTATE值不应以'00'开头,因为这样的值表示成功,并且对于发出错误信号无效。This is true whether the SQLSTATE value is specified directly in the SIGNAL statement or in a named condition referred to in the statement. 无论是在SIGNAL语句中直接指定SQLSTATE值,还是在语句中引用的命名条件中指定SQLSTATE值,都是如此。If the value is invalid, a Bad SQLSTATE error occurs.如果该值无效,则会发生Bad SQLSTATE错误。

To signal a generic SQLSTATE value, use '45000', which means unhandled user-defined exception.要发出通用SQLSTATE值的信号,请使用'45000',这意味着“未处理的用户定义异常”。

The SIGNAL statement optionally includes a SET clause that contains multiple signal items, in a list of condition_information_item_name = simple_value_specification assignments, separated by commas.SIGNAL语句可选地包括一个SET子句,该子句包含多个信号项,在condition_information_item_name=simple_value_specification分配的列表中,用逗号分隔。

Each condition_information_item_name may be specified only once in the SET clause. SET子句中,每个condition_information_item_name只能指定一次。Otherwise, a Duplicate condition information item error occurs.否则,将出现Duplicate condition information item错误。

Valid simple_value_specification designators can be specified using stored procedure or function parameters, stored program local variables declared with DECLARE, user-defined variables, system variables, or literals. 可以使用存储过程或函数参数、用DECLARE声明的存储程序局部变量、用户定义变量、系统变量或文字来指定有效的simple_value_specification指示符。A character literal may include a _charset introducer.字符文字可能包括_charset介绍人。

For information about permissible condition_information_item_name values, see Signal Condition Information Items.有关允许condition_information_item_name的信息,请参阅信号条件信息项

The following procedure signals an error or warning depending on the value of pval, its input parameter:以下程序根据其输入参数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;

If pval is 0, p() signals a warning because SQLSTATE values that begin with '01' are signals in the warning class. 如果pval为0,则p()会发出警告,因为以'01'开头的SQLSTATE值是警告类中的信号。The warning does not terminate the procedure, and can be seen with SHOW WARNINGS after the procedure returns.该警告不会终止该过程,在该过程返回后,可以通过SHOW WARNINGS看到该警告。

If pval is 1, p() signals an error and sets the MESSAGE_TEXT condition information item. 如果pval为1,则p()会发出错误信号,并设置MESSAGE_TEXT条件信息项。The error terminates the procedure, and the text is returned with the error information.该错误会终止该过程,并返回包含错误信息的文本。

If pval is 2, the same error is signaled, although the SQLSTATE value is specified using a named condition in this case.如果pval为2,则发出相同的错误信号,尽管在本例中使用命名条件指定了SQLSTATE值。

If pval is anything else, p() first signals a warning and sets the message text and error number condition information items. 如果pval是其他值,则p()首先发出警告信号,并设置消息文本和错误号条件信息项。This warning does not terminate the procedure, so execution continues and p() then signals an error. 此警告不会终止该过程,因此执行将继续,p()将发出错误信号。The error does terminate the procedure. The message text and error number set by the warning are replaced by the values set by the error, which are returned with the error information.该错误会终止该过程。警告设置的消息文本和错误号将替换为错误设置的值,这些值随错误信息一起返回。

SIGNAL is typically used within stored programs, but it is a MySQL extension that it is permitted outside handler context. SIGNAL通常在存储程序中使用,但它是一个MySQL扩展,允许在处理程序上下文之外使用。For example, if you invoke the mysql client program, you can enter any of these statements at the prompt:例如,如果调用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 executes according to the following rules:SIGNAL根据以下规则执行:

If the SIGNAL statement indicates a particular SQLSTATE value, that value is used to signal the condition specified. 如果SIGNAL语句指示特定的SQLSTATE值,则该值用于向指定的条件发送信号。Example:例如:

CREATE PROCEDURE p (divisor INT)
BEGIN
  IF divisor = 0 THEN
    SIGNAL SQLSTATE '22012';
  END IF;
END;

If the SIGNAL statement uses a named condition, the condition must be declared in some scope that applies to the SIGNAL statement, and must be defined using an SQLSTATE value, not a MySQL error number. 如果SIGNAL语句使用命名条件,则必须在适用于SIGNAL语句的某个范围内声明该条件,并且必须使用SQLSTATE值而不是MySQL错误号来定义该条件。Example:

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;

If the named condition does not exist in the scope of the SIGNAL statement, an Undefined CONDITION error occurs.如果指定的条件不在SIGNAL语句的范围内,则会发生Undefined CONDITION错误。

If SIGNAL refers to a named condition that is defined with a MySQL error number rather than an SQLSTATE value, a SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE error occurs. 如果SIGNAL引用的命名条件是用MySQL错误号定义的而不是SQLSTATE值定义的,则将发生SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE错误。The following statements cause that error because the named condition is associated with a MySQL error number:以下语句导致该错误,因为命名条件与MySQL错误号关联:

DECLARE no_such_table CONDITION FOR 1051;
SIGNAL no_such_table;

If a condition with a given name is declared multiple times in different scopes, the declaration with the most local scope applies. 如果在不同的作用域中多次声明具有给定名称的条件,则应用具有最局部作用域的声明。Consider the following procedure:考虑以下步骤:

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;

If divisor is 0, the first SIGNAL statement executes. 如果divisor为0,则执行第一个SIGNAL语句。The innermost my_error condition declaration applies, raising SQLSTATE '22012'.最内部的my_error条件声明将应用,并引发SQLSTATE '22012'

If divisor is not 0, the second SIGNAL statement executes. 如果divisor不是0,则执行第二个SIGNAL语句。The outermost my_error condition declaration applies, raising SQLSTATE '45000'.最外层的my_error条件声明将应用,并引发SQLSTATE '45000'。

For information about how the server chooses handlers when a condition occurs, see Section 13.6.7.6, “Scope Rules for Handlers”.有关出现条件时服务器如何选择处理程序的信息,请参阅第13.6.7.6节,“处理程序的范围规则”

Signals can be raised within exception handlers:可以在异常处理程序中引发信号:

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() reaches the DROP TABLE statement. CALL p()到达DROP TABLE语句。There is no table named no_such_table, so the error handler is activated. 没有名为no_such_table的表,因此错误处理程序被激活。The error handler destroys the original error (no such table) and makes a new error with SQLSTATE '99999' and message An error occurred.错误处理程序会销毁原始错误(“没有这样的表”),并使用SQLSTATE'99999'生成一个新错误,并显示一条发生错误的消息。

Signal Condition Information Items信号状态信息项

The following table lists the names of diagnostics area condition information items that can be set in a SIGNAL (or RESIGNAL) statement. 下表列出了可以在SIGNAL(或RESIGNAL)语句中设置的诊断区域条件信息项的名称。All items are standard SQL except MYSQL_ERRNO, which is a MySQL extension. MYSQL_ERRNO是MYSQL的扩展外,所有项目都是标准SQL。For more information about these items see Section 13.6.7.7, “The MySQL Diagnostics Area”.有关这些项目的更多信息,请参阅第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

The character set for character items is UTF-8.字符项的字符集是UTF-8。

It is illegal to assign NULL to a condition information item in a SIGNAL statement.SIGNAL语句中为条件信息项指定NULL是非法的。

A SIGNAL statement always specifies an SQLSTATE value, either directly, or indirectly by referring to a named condition defined with an SQLSTATE value. SIGNAL语句总是直接或间接地通过引用用SQLSTATE值定义的命名条件来指定SQLSTATE值。The first two characters of an SQLSTATE value are its class, and the class determines the default value for the condition information items:SQLSTATE值的前两个字符是其类,该类确定条件信息项的默认值:

  • Class = '00' (success)

    Illegal. 不合法。SQLSTATE values that begin with '00' indicate success and are not valid for SIGNAL.'00'开头的SQLSTATE值表示成功,对SIGNAL无效。

  • 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. SIGNAL执行后可以访问的错误值是SIGNAL语句和MESSAGE_TEXTMYSQL_ERRNO项引发的SQLSTATE值。These values are available from the C API:这些值可从C API获得:

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.在SQL级别,SHOW WARNINGSSHOW ERRORS的输出指示CodeMessage列中的MYSQL_ERRNOMESSAGE_TEXT值。

To retrieve information from the diagnostics area, use the GET DIAGNOSTICS statement (see Section 13.6.7.3, “GET DIAGNOSTICS Statement”). 要从诊断区域检索信息,请使用GET DIAGNOSTICS语句(参见第13.6.7.3节,“GET DIAGNOSTICS语句”)。For information about the diagnostics area, see Section 13.6.7.7, “The MySQL Diagnostics Area”.有关诊断区域的信息,请参阅第13.6.7.7节,“MySQL诊断区域”

Effect of Signals on Handlers, Cursors, and Statements信号对处理程序、游标和语句的影响

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忽略sql_mode系统变量的值;特别是,严格的SQL模式并不重要。MySQL also ignores IGNORE: The intent of SIGNAL is to raise a user-generated error explicitly, so a signal is never ignored.MySQL也会忽略IGNORESIGNAL的目的是显式地引发用户生成的错误,因此信号永远不会被忽略。

In the following descriptions, unhandled means that no handler for the signaled SQLSTATE value has been defined with DECLARE ... HANDLER.在下面的描述中,“unhandled”意味着没有用DECLARE ... HANDLER定义信号SQLSTATE值的处理程序。

  • Class = '00' (success)

    Illegal. 不合法的SQLSTATE values that begin with '00' indicate success and are not valid for SIGNAL.'00'开头的SQLSTATE值表示成功,对SIGNAL无效。

  • Class = '01' (warning)

    The value of the warning_count system variable goes up. warning_count系统变量的值上升。SHOW WARNINGS shows the signal. SHOW WARNINGS显示信号。SQLWARNING handlers catch the signal.SQLWARNING处理程序捕捉信号。

    Warnings cannot be returned from stored functions because the RETURN statement that causes the function to return clears the diagnostic area. 无法从存储函数返回警告,因为导致函数返回的RETURN语句会清除诊断区域。The statement thus clears any warnings that may have been present there (and resets warning_count to 0).因此,该语句将清除可能存在的所有警告(并将warning_count重置为0)。

  • Class = '02' (not found)

    NOT FOUND handlers catch the signal. NOT FOUND处理程序捕捉信号。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. SQLEXCEPTION处理程序捕捉信号。If the signal is unhandled in a stored function, statements end.如果在存储函数中未处理信号,则语句结束。

  • Class = '40'

    Treated as an ordinary exception.被视为普通的例外。