Documentation Home

13.6.7.5 SIGNAL 语句

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指示错误、警告或未找到。值的前两个字符表示其错误类别,如信号条件信息项中所述。某些信号值会导致语句终止;请参阅 信号对处理程序、游标和语句的影响

语句的SQLSTATESIGNAL不应以 开头,'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 for 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. These values are available from the 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.

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”.

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 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 for SIGNAL.

  • 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 resets warning_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'

    视为普通异常。