GET [CURRENT | STACKED] DIAGNOSTICS {statement_information_item
[,statement_information_item
] ... | CONDITIONcondition_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 statements produce diagnostic information that populates the diagnostics area. SQL语句生成填充诊断区域的诊断信息。The GET DIAGNOSTICS
statement enables applications to inspect this information.GET DIAGNOSTICS
语句允许应用程序检查此信息。 (You can also use (也可以使用SHOW WARNINGS
or SHOW ERRORS
to see conditions or errors.)SHOW WARNINGS
或SHOW ERRORS
来查看条件或错误。)
No special privileges are required to execute 执行GET DIAGNOSTICS
.GET DIAGNOSTICS
不需要特殊权限。
The keyword 关键字CURRENT
means to retrieve information from the current diagnostics area. CURRENT
表示从当前诊断区域检索信息。The keyword 关键字STACKED
means to retrieve information from the second diagnostics area, which is available only if the current context is a condition handler. STACKED
意味着从第二个诊断区域检索信息,该区域仅在当前上下文是条件处理程序时可用。If neither keyword is given, the default is to use the current diagnostics area.如果两个关键字都没有给出,默认情况下使用当前诊断区域。
The GET DIAGNOSTICS
statement is typically used in a handler within a stored program. GET DIAGNOSTICS
语句通常用于存储程序中的处理程序中。It is a MySQL extension that 它是一个MySQL扩展,允许GET [CURRENT] DIAGNOSTICS
is permitted outside handler context to check the execution of any SQL statement. GET [CURRENT] DIAGNOSTICS
在处理程序上下文之外检查任何SQL语句的执行情况。For example, if you invoke the mysql client program, you can enter these statements at the prompt:例如,如果调用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' | +-------+------------------------------------+
This extension applies only to the current diagnostics area. 此扩展仅适用于当前诊断区域。It does not apply to the second diagnostics area because 它不适用于第二个诊断区域,因为只有当当前上下文是条件处理程序时,才允许GET STACKED DIAGNOSTICS
is permitted only if the current context is a condition handler. GET STACKED DIAGNOSTICS
。If that is not the case, a 如果情况并非如此,则会发生GET STACKED DIAGNOSTICS when handler not active
error occurs.GET STACKED DIAGNOSTICS when handler not active
(处理程序未激活时获取堆叠诊断)错误。
For a description of the diagnostics area, see Section 13.6.7.7, “The MySQL Diagnostics Area”. 有关诊断区域的描述,请参阅第13.6.7.7节,“MySQL诊断区域”。Briefly, it contains two kinds of information:简而言之,它包含两种信息:
Statement information, such as the number of conditions that occurred or the affected-rows count.语句信息,例如发生的条件数或受影响的行数。
Condition information, such as the error code and message. 条件信息,例如错误代码和消息。If a statement raises multiple conditions, this part of the diagnostics area has a condition area for each one. 如果一条语句引发多个条件,则诊断区域的这一部分为每个条件都有一个条件区域。If a statement raises no conditions, this part of the diagnostics area is empty.如果语句没有引发任何条件,则诊断区域的这一部分为空。
For a statement that produces three conditions, the diagnostics area contains statement and condition information like this:对于产生三个条件的语句,诊断区域包含如下语句和条件信息:
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
can obtain either statement or condition information, but not both in the same statement:GET DIAGNOSTICS
可以获取语句或条件信息,但不能在同一语句中同时获取这两种信息:
To obtain statement information, retrieve the desired statement items into target variables. 要获取语句信息,请将所需的语句项检索到目标变量中。This instance of GET DIAGNOSTICS
assigns the number of available conditions and the rows-affected count to the user variables @p1
and @p2
:GET DIAGNOSTICS
的这个实例将可用条件的数量和受影响的行数分配给用户变量@p1
和@p2
:
GET DIAGNOSTICS @p1 = NUMBER, @p2 = ROW_COUNT;
To obtain condition information, specify the condition number and retrieve the desired condition items into target variables. 要获取条件信息,请指定条件编号,并将所需的条件项检索到目标变量中。This instance of GET DIAGNOSTICS
assigns the SQLSTATE value and error message to the user variables @p3
and @p4
:GET DIAGNOSTICS
的此实例将SQLSTATE值和错误消息分配给用户变量@p3
和@p4
:
GET DIAGNOSTICS CONDITION 1 @p3 = RETURNED_SQLSTATE, @p4 = MESSAGE_TEXT;
The retrieval list specifies one or more 检索列表指定一个或多个
assignments, separated by commas. target
= item_name
target = item_name
分配,用逗号分隔。Each assignment names a target variable and either a 每个赋值都命名一个目标变量和statement_information_item_name
or condition_information_item_name
designator, depending on whether the statement retrieves statement or condition information.statement_information_item_name
或condition_information_item_name
指示符,具体取决于该语句检索的是语句还是条件信息。
Valid 用于存储项信息的有效target
designators for storing item information can be stored procedure or function parameters, stored program local variables declared with DECLARE
, or user-defined variables.target
标识符可以是存储过程或函数参数、用DECLARE
声明的存储程序局部变量或用户定义的变量。
Valid 有效condition_number
designators can be stored procedure or function parameters, stored program local variables declared with DECLARE
, user-defined variables, system variables, or literals. condition_number
指示符可以是存储过程或函数参数、用DECLARE
声明的存储程序局部变量、用户定义变量、系统变量或文字。A character literal may include a 字符文字可能包括_charset
introducer. _charset
介绍人。A warning occurs if the condition number is not in the range from 1 to the number of condition areas that have information. 如果条件编号不在1到包含信息的条件区域数量的范围内,则会出现警告。In this case, the warning is added to the diagnostics area without clearing it.在这种情况下,警告会添加到诊断区域,而不会清除它。
When a condition occurs, MySQL does not populate all condition items recognized by 当出现条件时,MySQL不会填充GET DIAGNOSTICS
. GET DIAGNOSTICS
识别的所有条件项。For example:例如:
mysql>GET DIAGNOSTICS CONDITION 1
@p5 = SCHEMA_NAME, @p6 = TABLE_NAME;
mysql>SELECT @p5, @p6;
+------+------+ | @p5 | @p6 | +------+------+ | | | +------+------+
In standard SQL, if there are multiple conditions, the first condition relates to the 在标准SQL中,如果有多个条件,第一个条件与前一条SQL语句返回的SQLSTATE
value returned for the previous SQL statement. SQLSTATE
值有关。In MySQL, this is not guaranteed. 在MySQL中,这并不能保证。To get the main error, you cannot do this:要获取主要错误,您不能执行以下操作:
GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;
Instead, retrieve the condition count first, then use it to specify which condition number to inspect:相反,首先检索条件计数,然后使用它指定要检查的条件编号:
GET DIAGNOSTICS @cno = NUMBER; GET DIAGNOSTICS CONDITION @cno @errno = MYSQL_ERRNO;
For information about permissible statement and condition information items, and which ones are populated when a condition occurs, see Diagnostics Area Information Items.有关允许的语句和条件信息项的信息,以及条件发生时填充的信息,请参阅诊断区域信息项。
Here is an example that uses 下面是一个示例,它在存储过程上下文中使用GET DIAGNOSTICS
and an exception handler in stored procedure context to assess the outcome of an insert operation. GET DIAGNOSTICS
和异常处理程序来评估插入操作的结果。If the insert was successful, the procedure uses 如果插入成功,该过程将使用GET DIAGNOSTICS
to get the rows-affected count. GET DIAGNOSTICS
获取受影响的行数。This shows that you can use 这表明,只要当前诊断区域尚未清除,就可以多次使用GET DIAGNOSTICS
multiple times to retrieve information about a statement as long as the current diagnostics area has not been cleared.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;
Suppose that 假设t1.int_col
is an integer column that is declared as NOT NULL
. t1.int_col
是一个声明为NOT NULL
的整数列。The procedure produces these results when invoked to insert non-调用该过程分别插入非NULL
and NULL
values, respectively:NULL
值和NULL
值时,会生成以下结果:
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 | +-------------------------------------------------------------------------+
When a condition handler activates, a push to the diagnostics area stack occurs:当条件处理程序激活时,会推送到诊断区域堆栈:
The first (current) diagnostics area becomes the second (stacked) diagnostics area and a new current diagnostics area is created as a copy of it.第一个(当前)诊断区域成为第二个(堆叠)诊断区域,并创建一个新的当前诊断区域作为其副本。
GET [CURRENT] DIAGNOSTICS
and GET STACKED DIAGNOSTICS
can be used within the handler to access the contents of the current and stacked diagnostics areas.GET [CURRENT] DIAGNOSTICS
和GET STACKED DIAGNOSTICS
可在处理程序中用于访问当前和堆叠诊断区域的内容。
Initially, both diagnostics areas return the same result, so it is possible to get information from the current diagnostics area about the condition that activated the handler, as long as you execute no statements within the handler that change its current diagnostics area.最初,两个诊断区域返回相同的结果,因此,只要您在处理程序中不执行任何更改其当前诊断区域的语句,就可以从当前诊断区域获取有关激活处理程序的条件的信息。
However, statements executing within the handler can modify the current diagnostics area, clearing and setting its contents according to the normal rules (see How the Diagnostics Area is Cleared and Populated).但是,在处理程序中执行的语句可以修改当前诊断区域,根据正常规则清除和设置其内容(请参见如何清除和填充诊断区域)。
A more reliable way to obtain information about the handler-activating condition is to use the stacked diagnostics area, which cannot be modified by statements executing within the handler except 获取有关处理程序激活条件的信息的更可靠的方法是使用堆叠诊断区域,除了RESIGNAL
. RESIGNAL
之外,该区域不能由处理程序内执行的语句修改。For information about when the current diagnostics area is set and cleared, see Section 13.6.7.7, “The MySQL Diagnostics Area”.有关当前诊断区域何时设置和清除的信息,请参阅第13.6.7.7节,“MySQL诊断区域”。
The next example shows how 下一个示例显示了如何在处理程序中使用GET STACKED DIAGNOSTICS
can be used within a handler to obtain information about the handled exception, even after the current diagnostics area has been modified by handler statements.GET STACKED DIAGNOSTICS
来获取有关已处理异常的信息,即使当前诊断区域已被处理程序语句修改。
Within a stored procedure 在存储过程p()
, we attempt to insert two values into a table that contains a TEXT NOT NULL
column. p()
中,我们尝试将两个值插入到包含TEXT NOT NULL
列的表中。The first value is a non-第一个值是非NULL
string and the second is NULL
. NULL
字符串,第二个值是NULL
字符串。The column prohibits 该列禁止NULL
values, so the first insert succeeds but the second causes an exception. NULL
值,因此第一次插入成功,但第二次插入导致异常。The procedure includes an exception handler that maps attempts to insert 该过程包括一个异常处理程序,该处理程序将插入NULL
into inserts of the empty string:NULL
的尝试映射到空字符串的插入中:
DROP TABLE IF EXISTS t1; CREATE TABLE t1 (c1 TEXT NOT NULL); DROP PROCEDURE IF EXISTS p; delimiter // CREATE PROCEDURE p () BEGIN -- Declare variables to hold diagnostics area information DECLARE errcount INT; DECLARE errno INT; DECLARE msg TEXT; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- Here the current DA is nonempty because no prior statements -- executing within the handler have cleared it GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'current DA before mapped insert' AS op, errno, msg; GET STACKED DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'stacked DA before mapped insert' AS op, errno, msg; -- Map attempted NULL insert to empty string insert INSERT INTO t1 (c1) VALUES(''); -- Here the current DA should be empty (if the INSERT succeeded), -- so check whether there are conditions before attempting to -- obtain condition information GET CURRENT DIAGNOSTICS errcount = NUMBER; IF errcount = 0 THEN SELECT 'mapped insert succeeded, current DA is empty' AS op; ELSE GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'current DA after mapped insert' AS op, errno, msg; END IF ; GET STACKED DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'stacked DA after mapped insert' AS op, errno, msg; END; INSERT INTO t1 (c1) VALUES('string 1'); INSERT INTO t1 (c1) VALUES(NULL); END; // delimiter ; CALL p(); SELECT * FROM t1;
When the handler activates, a copy of the current diagnostics area is pushed to the diagnostics area stack. 当处理程序激活时,当前诊断区域的副本被推送到诊断区域堆栈。The handler first displays the contents of the current and stacked diagnostics areas, which are both the same initially:处理程序首先显示当前和堆叠诊断区域的内容,这两个区域最初是相同的:
+---------------------------------+-------+----------------------------+ | op | errno | msg | +---------------------------------+-------+----------------------------+ | current DA before mapped insert | 1048 | Column 'c1' cannot be null | +---------------------------------+-------+----------------------------+ +---------------------------------+-------+----------------------------+ | op | errno | msg | +---------------------------------+-------+----------------------------+ | stacked DA before mapped insert | 1048 | Column 'c1' cannot be null | +---------------------------------+-------+----------------------------+
Statements executing after the GET DIAGNOSTICS
statements may reset the current diagnostics area. GET DIAGNOSTICS
语句之后执行的语句可能会重置当前诊断区域。statements may reset the current diagnostics area. 语句可能会重置当前诊断区域。For example, the handler maps the 例如,处理程序将空插入映射为空字符串插入,并显示结果。NULL
insert to an empty-string insert and displays the result. The new insert succeeds and clears the current diagnostics area, but the stacked diagnostics area remains unchanged and still contains information about the condition that activated the handler:新的插入成功并清除当前的诊断区域,但堆叠的诊断区域保持不变,仍然包含有关激活处理程序的条件的信息:
+----------------------------------------------+ | op | +----------------------------------------------+ | mapped insert succeeded, current DA is empty | +----------------------------------------------+ +--------------------------------+-------+----------------------------+ | op | errno | msg | +--------------------------------+-------+----------------------------+ | stacked DA after mapped insert | 1048 | Column 'c1' cannot be null | +--------------------------------+-------+----------------------------+
When the condition handler ends, its current diagnostics area is popped from the stack and the stacked diagnostics area becomes the current diagnostics area in the stored procedure.当条件处理程序结束时,其当前诊断区域将从堆栈中弹出,并且堆叠的诊断区域将成为存储过程中的当前诊断区域。
After the procedure returns, the table contains two rows. 过程返回后,该表包含两行。The empty row results from the attempt to insert 空行是由于尝试插入映射到空字符串插入的NULL
that was mapped to an empty-string insert:NULL
导致的:
+----------+ | c1 | +----------+ | string 1 | | | +----------+
In the preceding example, the first two 在前面的示例中,条件处理程序中从当前和堆叠的诊断区域检索信息的前两个GET DIAGNOSTICS
statements within the condition handler that retrieve information from the current and stacked diagnostics areas return the same values. GET DIAGNOSTICS
语句返回相同的值。This is not the case if statements that reset the current diagnostics area execute earlier within the handler. 如果重置当前诊断区域的语句更早地在处理程序中执行,则情况并非如此。Suppose that 假设p()
is rewritten to place the DECLARE
statements within the handler definition rather than preceding it:p()
被重写,将DECLARE
语句放在处理程序定义中,而不是放在它前面:
CREATE PROCEDURE p () BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- Declare variables to hold diagnostics area information DECLARE errcount INT; DECLARE errno INT; DECLARE msg TEXT; GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'current DA before mapped insert' AS op, errno, msg; GET STACKED DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'stacked DA before mapped insert' AS op, errno, msg; ...
In this case, the result is version dependent:在这种情况下,结果取决于版本:
Before MySQL 5.7.2, 在MySQL 5.7.2之前,DECLARE
does not change the current diagnostics area, so the first two GET DIAGNOSTICS
statements return the same result, just as in the original version of p()
.DECLARE
不会更改当前的诊断区域,因此前两个GET DIAGNOSTICS
语句返回相同的结果,就像原始版本的p()
一样。
In MySQL 5.7.2, work was done to ensure that all nondiagnostic statements populate the diagnostics area, per the SQL standard. 在MySQL 5.7.2中,按照SQL标准,确保所有非诊断语句都填充诊断区域。DECLARE
is one of them, so in 5.7.2 and higher, DECLARE
statements executing at the beginning of the handler clear the current diagnostics area and the GET DIAGNOSTICS
statements produce different results:DECLARE
是其中之一,因此在5.7.2及更高版本中,在处理程序开头执行的DECLARE
语句会清除当前诊断区域,GET DIAGNOSTICS
语句会产生不同的结果:
+---------------------------------+-------+------+ | op | errno | msg | +---------------------------------+-------+------+ | current DA before mapped insert | NULL | NULL | +---------------------------------+-------+------+ +---------------------------------+-------+----------------------------+ | op | errno | msg | +---------------------------------+-------+----------------------------+ | stacked DA before mapped insert | 1048 | Column 'c1' cannot be null | +---------------------------------+-------+----------------------------+
To avoid this issue within a condition handler when seeking to obtain information about the condition that activated the handler, be sure to access the stacked diagnostics area, not the current diagnostics area.为了避免在条件处理程序中出现此问题,当试图获取激活处理程序的条件的信息时,请确保访问堆叠的诊断区域,而不是当前的诊断区域。