#### 13.6.7.5 信号声明

[](<>)

```
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.html)是“返回”错误的方法。[`信号`](signal.html)向处理程序、应用程序的外部或客户端提供错误信息。此外，它还提供对错误特征的控制（错误编号、`SQLSTATE`值，消息）。没有[`信号`](signal.html)，有必要诉诸变通方法，例如故意引用不存在的表以导致例程返回错误。

无需权限即可执行[`信号`](signal.html)陈述。

要从诊断区域检索信息，请使用[`得到诊断`](get-diagnostics.html)声明（见[第 13.6.7.3 节，“获取诊断声明”](get-diagnostics.html)）。有关诊断区域的信息，请参阅[第 13.6.7.7 节，“MySQL 诊断区域”](diagnostics-area.html).

-   [信号概述](signal.html#signal-overview)

-   [信号条件信息项](signal.html#signal-condition-information-items)

-   [信号对处理程序、游标和语句的影响](signal.html#signal-effects)

##### 信号概述

这*`条件值`*在一个[`信号`](signal.html)statement 表示要返回的错误值。它可以是一个`SQLSTATE`值（5 个字符的字符串文字）或*`条件名称`*指的是之前使用定义的命名条件[`声明条件`](declare-condition.html)（见[第13.6.7.1节，“声明……条件声明”](declare-condition.html)).

一`SQLSTATE`值可以指示错误、警告或“未找到”值的前两个字符表示其错误类别，如中所述[信号状态信息项](signal.html#signal-condition-information-items).一些信号值导致语句终止；看见[信号对处理程序、游标和语句的影响](signal.html#signal-effects).

这个`SQLSTATE`价值[`信号`](signal.html)声明不应以`'00'`因为这样的值表示成功，并且对于发出错误信号无效。无论`SQLSTATE`值直接在[`信号`](signal.html)语句或语句中引用的命名条件。如果该值无效，则`糟糕的SQL状态`发生错误。

发出通用信号`SQLSTATE`价值，使用`'45000'`，表示“未处理的用户定义异常”

这个[`信号`](signal.html)语句可选地包括`设置`包含多个信号项的子句，在*`条件信息项目名称`* = *`简单值规范`*作业，用逗号分隔。

每个*`条件信息项目名称`*只能在列表中指定一次`设置`条款否则，一个`重复条件信息项`发生错误。

有效的*`简单值规范`*可以使用存储过程或函数参数、用[`声明`](declare.html)，用户定义变量、系统变量或文字。字符文字可以包括*`_charset`*介绍人。

有关许可的信息*`条件信息项目名称`*价值观，参见[信号状态信息项](signal.html#signal-condition-information-items).

以下步骤根据的值发出错误或警告信号`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.html)在程序返回后。

如果`pval`是1，`p（）`发出错误信号并设置`短信`条件信息项。该错误会终止该过程，并返回包含错误信息的文本。

如果`pval`如果为2，则会发出相同的错误信号，尽管`SQLSTATE`在本例中，值是使用命名条件指定的。

如果`pval`还有别的吗，`p（）`首先发出警告信号，并设置消息文本和错误号条件信息项。此警告不会终止该过程，因此继续执行并`p（）`然后发出错误信号。该错误会终止该过程。警告设置的消息文本和错误号将替换为错误设置的值，这些值随错误信息一起返回。

[`信号`](signal.html)通常在存储程序中使用，但它是允许在处理程序上下文之外使用的MySQL扩展。例如，如果调用[**mysql**](mysql.html)在客户端程序中，您可以在提示符下输入以下任何语句：

```
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.html)根据以下规则执行：

如果[`信号`](signal.html)语句表示一个特定的`SQLSTATE`值，该值用于表示指定的条件。例子：

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

如果[`信号`](signal.html)语句使用命名条件时，必须在应用于[`信号`](signal.html)语句，并且必须使用`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.html)声明`未定义条件`发生错误。

如果[`信号`](signal.html)指的是使用MySQL错误号而不是`SQLSTATE`价值，a`SIGNAL/RESIGNAL只能使用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;
```

如果`除数`是0，第一个[`信号`](signal.html)语句执行。最深处`我的错误`条件声明适用，提出`SQLSTATE` `'22012'`.

如果`除数`不是0，第二个[`信号`](signal.html)语句执行。最外层`我的错误`条件声明适用，提出`SQLSTATE` `'45000'`.

有关发生条件时服务器如何选择处理程序的信息，请参阅[第13.6.7.6节，“处理人员的范围规则”](handler-scope.html).

可以在异常处理程序中引发信号：

```
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;
```

`呼叫p（）`到达[`升降台`](drop-table.html)陈述没有名为的表`没有这样的桌子`，因此错误处理程序被激活。错误处理程序销毁原始错误（“没有这样的表”），并使用`SQLSTATE` `'99999'`和信息`发生了一个错误`.

##### 信号状态信息项

下表列出了诊断区域条件信息项的名称，这些信息项可以在[`信号`](signal.html)（或[`辞职的`](resignal.html))声明。除SQL外，所有项目都是标准SQL`乌尔诺`，这是一个MySQL扩展。有关这些项目的更多信息，请参阅[第13.6.7.7节，“MySQL诊断区域”](diagnostics-area.html).

```
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.html)陈述

A.[`信号`](signal.html)语句始终指定`SQLSTATE`值，直接或间接地通过引用使用`SQLSTATE`价值一个单词的前两个字符`SQLSTATE`值是其类，该类确定条件信息项的默认值：

-   类别=`'00'`（成功）

    不合法的`SQLSTATE`以`'00'`表示成功，但不适用于[`信号`](signal.html).

-   类别=`'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.html)执行是最重要的`SQLSTATE`资产增值[`信号`](signal.html)声明和`短信`和`乌尔诺`项目。这些值可从C API获得：

-   [`mysql_sqlstate（）`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-sqlstate.html)返回`SQLSTATE`价值

-   [`mysql_errno（）`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-errno.html)返回`乌尔诺`价值

-   [`mysql_error（）`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-error.html)返回`短信`价值

    在SQL级别，来自[`显示警告`](show-warnings.html)和[`显示错误`](show-errors.html)表示`乌尔诺`和`短信`价值观`密码`和`消息`柱。

    要从诊断区域检索信息，请使用[`获取诊断信息`](get-diagnostics.html)声明（见[第13.6.7.3节，“获取诊断声明”](get-diagnostics.html)).有关诊断区域的信息，请参阅[第13.6.7.7节，“MySQL诊断区域”](diagnostics-area.html).

##### 信号对处理程序、游标和语句的影响

信号对语句执行的影响因信号类而异。该类确定错误的严重程度。MySQL忽略了[`sql_模式`](server-system-variables.html#sysvar_sql_mode)系统变量；特别是，严格的SQL模式并不重要。MySQL也忽略了这一点`忽视`：目的[`信号`](signal.html)就是显式地引发用户生成的错误，所以信号永远不会被忽略。

在下面的描述中，“unhandled”意味着没有信号处理程序`SQLSTATE`值已用定义[`声明处理者`](declare-handler.html).

-   类别=`'00'`（成功）

    不合法的`SQLSTATE`以`'00'`表示成功，但不适用于[`信号`](signal.html).

-   类别=`'01'`（警告）

    价值[`警告!`](server-system-variables.html#sysvar_warning_count)系统变量上升。[`显示警告`](show-warnings.html)显示信号。`SQLWARNING`处理程序捕捉到信号。

    无法从存储函数返回警告，因为[`回来`](return.html)导致函数返回的语句将清除诊断区域。因此，该声明清除了可能存在的任何警告（并重置）[`警告!`](server-system-variables.html#sysvar_warning_count)0）。

-   类别=`'02'`（未找到）

    `找不到`处理程序捕捉到信号。对游标没有影响。如果在存储函数中未处理信号，则语句结束。

-   班> `'02'`（例外）

    `SQLEXCEPTION`处理程序捕捉到信号。如果在存储函数中未处理信号，则语句结束。

-   类别=`'40'`

    被视为普通的例外。
