Rechercher dans le manuel MySQL

13.6.7.3 GET DIAGNOSTICS Syntax

  1. GET [CURRENT | STACKED] DIAGNOSTICS
  2. {
  3.     statement_information_item
  4.     [, statement_information_item] ...
  5.   | CONDITION condition_number
  6.     condition_information_item
  7.     [, condition_information_item] ...
  8. }
  9.  
  10. statement_information_item:
  11.     target = statement_information_item_name
  12.  
  13. condition_information_item:
  14.     target = condition_information_item_name
  15.  
  16. statement_information_item_name:
  17.     NUMBER
  18.  
  19. condition_information_item_name: {
  20.     CLASS_ORIGIN
  21.   | SUBCLASS_ORIGIN
  22.   | RETURNED_SQLSTATE
  23.   | MESSAGE_TEXT
  24.   | MYSQL_ERRNO
  25.   | CONSTRAINT_CATALOG
  26.   | CONSTRAINT_SCHEMA
  27.   | CONSTRAINT_NAME
  28.   | CATALOG_NAME
  29.   | SCHEMA_NAME
  30.   | TABLE_NAME
  31.   | COLUMN_NAME
  32.   | CURSOR_NAME
  33. }
  34.  
  35. condition_number, target:
  36.     (see following discussion)

SQL statements produce diagnostic information that populates the diagnostics area. The GET DIAGNOSTICS statement enables applications to inspect this information. (You can also use SHOW WARNINGS or SHOW ERRORS to see conditions or errors.)

No special privileges are required to execute GET DIAGNOSTICS.

The keyword CURRENT means to retrieve information from the current diagnostics area. The keyword STACKED 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.

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

  1. mysql> DROP TABLE test.no_such_table;
  2. ERROR 1051 (42S02): Unknown table 'test.no_such_table'
  3. mysql> GET DIAGNOSTICS CONDITION 1
  4.          @p1 = RETURNED_SQLSTATE, @p2 = MESSAGE_TEXT;
  5. mysql> SELECT @p1, @p2;
  6. +-------+------------------------------------+
  7. | @p1   | @p2                                |
  8. +-------+------------------------------------+
  9. | 42S02 | Unknown table 'test.no_such_table' |
  10. +-------+------------------------------------+

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. If that is not the case, a GET STACKED DIAGNOSTICS when handler not active error occurs.

For a description of the diagnostics area, see Section 13.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 of GET DIAGNOSTICS assigns the number of available conditions and the rows-affected count to the user variables @p1 and @p2:

    1. 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:

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

The retrieval list specifies one or more target = item_name assignments, separated by commas. 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.

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.

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. 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 by GET DIAGNOSTICS. For example:

  1. mysql> GET DIAGNOSTICS CONDITION 1
  2.          @p5 = SCHEMA_NAME, @p6 = TABLE_NAME;
  3. mysql> SELECT @p5, @p6;
  4. +------+------+
  5. | @p5  | @p6  |
  6. +------+------+
  7. |      |      |
  8. +------+------+

In standard SQL, if there are multiple conditions, the first condition relates to the SQLSTATE value returned for the previous SQL statement. In MySQL, this is not guaranteed. To get the main error, you cannot do this:

  1. GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;

Instead, retrieve the condition count first, then use it to specify which condition number to inspect:

  1. GET DIAGNOSTICS @cno = NUMBER;
  2. 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. If the insert was successful, the procedure uses GET DIAGNOSTICS to get the rows-affected count. 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.

  1.   -- Declare variables to hold diagnostics area information
  2.   DECLARE code CHAR(5) DEFAULT '00000';
  3.   DECLARE msg TEXT;
  4.   DECLARE rows INT;
  5.   DECLARE result TEXT;
  6.   -- Declare exception handler for failed insert
  7.   DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
  8.     BEGIN
  9.       GET DIAGNOSTICS CONDITION 1
  10.         code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
  11.     END;
  12.  
  13.   -- Perform the insert
  14.   INSERT INTO t1 (int_col) VALUES(value);
  15.   -- Check whether the insert was successful
  16.   IF code = '00000' THEN
  17.     GET DIAGNOSTICS rows = ROW_COUNT;
  18.     SET result = CONCAT('insert succeeded, row count = ',rows);
  19.   ELSE
  20.     SET result = CONCAT('insert failed, error = ',code,', message = ',msg);
  21.   END IF;
  22.   -- Say what happened
  23.   SELECT result;

Suppose that t1.int_col is an integer column that is declared as NOT NULL. The procedure produces these results when invoked to insert non-NULL and NULL values, respectively:

  1. mysql> CALL do_insert(1);
  2. +---------------------------------+
  3. | result                          |
  4. +---------------------------------+
  5. | insert succeeded, row count = 1 |
  6. +---------------------------------+
  7.  
  8. mysql> CALL do_insert(NULL);
  9. +-------------------------------------------------------------------------+
  10. | result                                                                  |
  11. +-------------------------------------------------------------------------+
  12. | insert failed, error = 23000, message = Column 'int_col' cannot be null |
  13. +-------------------------------------------------------------------------+

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.

  • 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. For information about when the current diagnostics area is set and cleared, see Section 13.6.7.7, “The MySQL Diagnostics Area”.

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.

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

  1. delimiter //
  2.   -- Declare variables to hold diagnostics area information
  3.   DECLARE errcount INT;
  4.   DECLARE errno INT;
  5.   DECLARE msg TEXT;
  6.   DECLARE EXIT HANDLER FOR SQLEXCEPTION
  7.     -- Here the current DA is nonempty because no prior statements
  8.     -- executing within the handler have cleared it
  9.     GET CURRENT DIAGNOSTICS CONDITION 1
  10.       errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  11.     SELECT 'current DA before mapped insert' AS op, errno, msg;
  12.     GET STACKED DIAGNOSTICS CONDITION 1
  13.       errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  14.     SELECT 'stacked DA before mapped insert' AS op, errno, msg;
  15.  
  16.     -- Map attempted NULL insert to empty string insert
  17.     INSERT INTO t1 (c1) VALUES('');
  18.  
  19.     -- Here the current DA should be empty (if the INSERT succeeded),
  20.     -- so check whether there are conditions before attempting to
  21.     -- obtain condition information
  22.     GET CURRENT DIAGNOSTICS errcount = NUMBER;
  23.     IF errcount = 0
  24.     THEN
  25.       SELECT 'mapped insert succeeded, current DA is empty' AS op;
  26.     ELSE
  27.       GET CURRENT DIAGNOSTICS CONDITION 1
  28.         errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  29.       SELECT 'current DA after mapped insert' AS op, errno, msg;
  30.     END IF ;
  31.     GET STACKED DIAGNOSTICS CONDITION 1
  32.       errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  33.     SELECT 'stacked DA after mapped insert' AS op, errno, msg;
  34.   END;
  35.   INSERT INTO t1 (c1) VALUES('string 1');
  36.   INSERT INTO t1 (c1) VALUES(NULL);
  37. //
  38. delimiter ;
  39. CALL p();
  40. 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. 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:

+----------+
| 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. This will not be 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:

  1.   DECLARE EXIT HANDLER FOR SQLEXCEPTION
  2.     -- Declare variables to hold diagnostics area information
  3.     DECLARE errcount INT;
  4.     DECLARE errno INT;
  5.     DECLARE msg TEXT;
  6.     GET CURRENT DIAGNOSTICS CONDITION 1
  7.       errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  8.     SELECT 'current DA before mapped insert' AS op, errno, msg;
  9.     GET STACKED DIAGNOSTICS CONDITION 1
  10.       errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  11.     SELECT 'stacked DA before mapped insert' AS op, errno, msg;
  12. ...

In this case, the result is version dependent:

  • Before 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().

    In MySQL 5.7.2, work was done to ensure that all nondiagnostic statements populate the diagnostics area, per the SQL standard. 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:

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


Rechercher dans le manuel MySQL

Traduction non disponible

Le manuel MySQL n'est pas encore traduit en français sur l'infobrol. Seule la version anglaise est disponible pour l'instant.

Document créé le 26/06/2006, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/mysql-rf-get-diagnostics.html

L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.

Références

  1. Consulter le document html Langue du document :en Manuel MySQL : https://dev.mysql.com/

Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.

Table des matières Haut