Documentation Home
MySQL 8.0 参考手册  / 第 13 章 SQL 语句  / 13.6 复合语句语法  / 13.6.7 条件处理  /  13.6.7.3 GET DIAGNOSTICS 语句

13.6.7.3 GET DIAGNOSTICS 语句

GET [CURRENT] DIAGNOSTICS {
    statement_information_item
    [, statement_information_item] ...
  | CONDITION condition_number
    condition_information_item
    [, condition_information_item] ...
}

statement_information_item:
    target = statement_information_item_name

condition_information_item:
    target = condition_information_item_name

statement_information_item_name: {
    NUMBER
  | ROW_COUNT
}

condition_information_item_name: {
    CLASS_ORIGIN
  | SUBCLASS_ORIGIN
  | RETURNED_SQLSTATE
  | MESSAGE_TEXT
  | MYSQL_ERRNO
  | CONSTRAINT_CATALOG
  | CONSTRAINT_SCHEMA
  | CONSTRAINT_NAME
  | CATALOG_NAME
  | SCHEMA_NAME
  | TABLE_NAME
  | COLUMN_NAME
  | CURSOR_NAME
}

condition_number, target:
    (see following discussion)

SQL 语句产生填充诊断区域的诊断信息。该GET DIAGNOSTICS语句使应用程序能够检查此信息。它从 MySQL 5.6.4 开始可用。(您也可以使用SHOW WARNINGSor SHOW ERRORS来查看条件或错误。)

执行不需要特殊权限 GET DIAGNOSTICS

关键字CURRENT表示从当前诊断区域检索信息。在 MySQL 中,它没有效果,因为这是默认行为。

GET DIAGNOSTICS通常在存储程序中的处理程序中使用,但它是 MySQL 扩展,允许在处理程序上下文之外检查任何 SQL 语句的执行。例如调用mysql客户端程序,可以在提示符下输入这些语句:

mysql> DROP TABLE test.no_such_table;
ERROR 1051 (42S02): Unknown table 'test.no_such_table'
mysql> GET DIAGNOSTICS CONDITION 1
         @p1 = RETURNED_SQLSTATE, @p2 = MESSAGE_TEXT;
mysql> SELECT @p1, @p2;
+-------+------------------------------------+
| @p1   | @p2                                |
+-------+------------------------------------+
| 42S02 | Unknown table 'test.no_such_table' |
+-------+------------------------------------+

有关诊断区域的描述,请参阅 第 13.6.7.7 节,“MySQL 诊断区域”。简而言之,它包含两种信息:

  • 语句信息,例如发生的条件数或受影响的行数。

  • 条件信息,例如错误代码和消息。如果语句引发多个条件,则诊断区域的这一部分对每个条件都有一个条件区域。如果语句未引发任何条件,则诊断区域的这一部分为空。

对于产生三个条件的语句,诊断区域包含如下语句和条件信息:

Statement information:
  row count
  ... other statement information items ...
Condition area list:
  Condition area 1:
    error code for condition 1
    error message for condition 1
    ... other condition information items ...
  Condition area 2:
    error code for condition 2:
    error message for condition 2
    ... other condition information items ...
  Condition area 3:
    error code for condition 3
    error message for condition 3
    ... other condition information items ...

GET DIAGNOSTICS可以获取语句或条件信息,但不能在同一语句中同时获取两者:

  • 要获取语句信息,请将所需的语句项检索到目标变量中。此实例 GET DIAGNOSTICS将可用条件的数量和受影响的行数分配给用户变量@p1and @p2

    GET DIAGNOSTICS @p1 = NUMBER, @p2 = ROW_COUNT;
  • 要获取条件信息,请指定条件编号并将所需的条件项检索到目标变量中。此实例GET DIAGNOSTICS将 SQLSTATE 值和错误消息分配给用户变量@p3并且 @p4

    GET DIAGNOSTICS CONDITION 1
      @p3 = RETURNED_SQLSTATE, @p4 = MESSAGE_TEXT;

检索列表指定一个或多个 分配,以逗号分隔。每个赋值命名一个目标变量和一个 或 指示符,这取决于该语句是检索语句信息还是条件信息。 target = item_namestatement_information_item_namecondition_information_item_name

用于存储项目信息的有效target指示符可以是存储过程或函数参数、用 声明的存储程序局部变量 DECLARE或用户定义的变量。

有效condition_number的指示符可以是存储过程或函数参数、用 声明的存储程序局部变量 DECLARE、用户定义的变量、系统变量或文字。字符字面量可以包括 _charset介绍人。如果条件编号不在从 1 到具有信息的条件区域数的范围内,则会出现警告。在这种情况下,警告会添加到诊断区域而不清除它。

当条件发生时,MySQL 不会填充GET DIAGNOSTICS. 例如:

mysql> GET DIAGNOSTICS CONDITION 1
         @p5 = SCHEMA_NAME, @p6 = TABLE_NAME;
mysql> SELECT @p5, @p6;
+------+------+
| @p5  | @p6  |
+------+------+
|      |      |
+------+------+

在标准 SQL 中,如果有多个条件,则第一个条件与SQLSTATE前一个 SQL 语句的返回值相关。在 MySQL 中,这是无法保证的。要获得主要错误,您不能这样做:

GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;

相反,首先检索条件计数,然后使用它指定要检查的条件数:

GET DIAGNOSTICS @cno = NUMBER;
GET DIAGNOSTICS CONDITION @cno @errno = MYSQL_ERRNO;

有关允许的语句和条件信息项的信息,以及在条件发生时填充哪些信息项,请参阅 诊断区域信息项

下面是一个示例,它GET DIAGNOSTICS在存储过程上下文中使用异常处理程序来评估插入操作的结果。如果插入成功,该过程将 GET DIAGNOSTICS用于获取受影响的行数。这表明 GET DIAGNOSTICS只要诊断区域未被清除,您就可以使用多次来检索有关语句的信息。

CREATE PROCEDURE do_insert(value INT)
BEGIN
  -- Declare variables to hold diagnostics area information
  DECLARE code CHAR(5) DEFAULT '00000';
  DECLARE msg TEXT;
  DECLARE nrows INT;
  DECLARE result TEXT;
  -- Declare exception handler for failed insert
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
    BEGIN
      GET DIAGNOSTICS CONDITION 1
        code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
    END;

  -- Perform the insert
  INSERT INTO t1 (int_col) VALUES(value);
  -- Check whether the insert was successful
  IF code = '00000' THEN
    GET DIAGNOSTICS nrows = ROW_COUNT;
    SET result = CONCAT('insert succeeded, row count = ',nrows);
  ELSE
    SET result = CONCAT('insert failed, error = ',code,', message = ',msg);
  END IF;
  -- Say what happened
  SELECT result;
END;

假设那t1.int_col是一个声明为的整数列NOT NULL。该过程在被调用以分别插入非值NULLNULL值时产生这些结果:

mysql> CALL do_insert(1);
+---------------------------------+
| result                          |
+---------------------------------+
| insert succeeded, row count = 1 |
+---------------------------------+

mysql> CALL do_insert(NULL);
+-------------------------------------------------------------------------+
| result                                                                  |
+-------------------------------------------------------------------------+
| insert failed, error = 23000, message = Column 'int_col' cannot be null |
+-------------------------------------------------------------------------+

在条件处理程序中,GET DIAGNOSTICS应该在其他语句之前使用,这些语句可能会清除诊断区域并导致有关激活处理程序的条件的信息丢失。有关何时设置和清除诊断区域的信息,请参阅第 13.6.7.7 节,“MySQL 诊断区域”