Documentation Home
MySQL 9.1 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.4Mb
PDF (A4) - 40.5Mb
Man Pages (TGZ) - 259.5Kb
Man Pages (Zip) - 366.7Kb
Info (Gzip) - 4.1Mb
Info (Zip) - 4.1Mb


15.6.7.3 GET DIAGNOSTICS Statement

GET [CURRENT | STACKED] DIAGNOSTICS {statement_information_item    [,statement_information_item] ...  | CONDITIONcondition_numbercondition_information_item    [,condition_information_item] ...}statement_information_item:target =statement_information_item_namecondition_information_item:target =condition_information_item_namestatement_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. TheGET DIAGNOSTICS statement enables applications to inspect this information. (You can also useSHOW WARNINGS orSHOW ERRORS to see conditions or errors.)

No special privileges are required to executeGET DIAGNOSTICS.

The keywordCURRENT means to retrieve information from the current diagnostics area. The keywordSTACKED means to retrieve information from the second diagnostics area, which is available only if the current context is a condition handler. If neither keyword is given, the default is to use the current diagnostics area.

TheGET DIAGNOSTICS statement is typically used in a handler within a stored program. It is a MySQL extension thatGET [CURRENT] DIAGNOSTICS is permitted outside handler context to check the execution of any SQL statement. For example, if you invoke themysql client program, you can enter these statements at the prompt:

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 becauseGET STACKED DIAGNOSTICS is permitted only if the current context is a condition handler. If that is not the case, aGET STACKED DIAGNOSTICS when handler not active error occurs.

For a description of the diagnostics area, seeSection 15.6.7.7, “The MySQL Diagnostics Area”. 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:

  • To obtain statement information, retrieve the desired statement items into target variables. This instance ofGET DIAGNOSTICS assigns the number of available conditions and the rows-affected count to the user variables@p1 and@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 ofGET DIAGNOSTICS assigns the SQLSTATE value and error message to the user variables@p3 and@p4:

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

The retrieval list specifies one or moretarget =item_name assignments, separated by commas. Each assignment names a target variable and either astatement_information_item_name orcondition_information_item_name designator, depending on whether the statement retrieves statement or condition information.

Validtarget designators for storing item information can be stored procedure or function parameters, stored program local variables declared withDECLARE, or user-defined variables.

Validcondition_number designators can be stored procedure or function parameters, stored program local variables declared withDECLARE, user-defined variables, system variables, or literals. A character literal may include a_charset introducer. A warning occurs if the condition number is not in the range from 1 to the number of condition areas that have information. 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 byGET 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 theSQLSTATE value returned for the previous SQL statement. In MySQL, this is not guaranteed. 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, seeDiagnostics Area Information Items.

Here is an example that usesGET DIAGNOSTICS and an exception handler in stored procedure context to assess the outcome of an insert operation. If the insert was successful, the procedure usesGET DIAGNOSTICS to get the rows-affected count. This shows that you can useGET DIAGNOSTICS multiple times to retrieve information about a statement as long as the current diagnostics area has not been cleared.

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 thatt1.int_col is an integer column that is declared asNOT NULL. The procedure produces these results when invoked to insert non-NULL andNULL values, respectively:

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 andGET STACKED DIAGNOSTICS can be used within the handler to access the contents of the current and stacked diagnostics areas.

  • 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 (seeHow 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 exceptRESIGNAL. For information about when the current diagnostics area is set and cleared, seeSection 15.6.7.7, “The MySQL Diagnostics Area”.

The next example shows howGET 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.

Within a stored procedurep(), we attempt to insert two values into a table that contains aTEXT NOT NULL column. The first value is a non-NULL string and the second isNULL. The column prohibitsNULL values, so the first insert succeeds but the second causes an exception. The procedure includes an exception handler that maps attempts to insertNULL into inserts of the empty string:

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 theGET DIAGNOSTICS statements may reset the current diagnostics area. statements may reset the current diagnostics area. For example, the handler maps theNULL 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 insertNULL that was mapped to an empty-string insert:

+----------+| c1       |+----------+| string 1 ||          |+----------+