15.6.7.3 Выражение GET DIAGNOSTICS
GET [CURRENT | STACKED] 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 позволяет приложениям инспектировать эту информацию. (Вы также можете использовать SHOW
WARNINGS или SHOW ERRORS для просмотра условий или ошибок.)
Для выполнения GET DIAGNOSTICS не требуется специальных привилегий.
Ключевое слово CURRENT означает извлечение информации из текущей области диагностики. Ключевое слово STACKED означает извлечение информации из второй области диагностики, которая доступна только если текущий контекст — обработчик условий. Если ни одно из этих ключевых слов не указано, используется текущая область диагностики по умолчанию.
Выражение GET DIAGNOSTICS обычно используется в обработчике внутри хранимой программы. Это расширение MySQL, которое GET [CURRENT]
DIAGNOSTICS допускает использование вне контекста обработчика для проверки выполнения любого 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' |
+-------+------------------------------------+
Это расширение применяется только к текущей области диагностики. Оно не применяется ко второй области диагностики, поскольку GET STACKED DIAGNOSTICS разрешено только если текущий контекст — обработчик условий. Если это не так, возникает ошибка GET STACKED DIAGNOSTICS when handler not
active.
Описание области диагностики см. в разделе 15.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присваивает количество доступных условий и количество затронутых строк пользовательским переменным@p1и@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_name, либо condition_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. Процедура дает эти результаты при вызове для вставки значений, не являющихся 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 |
+-------------------------------------------------------------------------+
Когда активируется обработчик условий, происходит занесение в стек области диагностики:
Первая (текущая) область диагностики становится второй (стековой) областью диагностики, и создается новая текущая область диагностики как ее копия.
GET [CURRENT] DIAGNOSTICSиGET STACKED DIAGNOSTICSмогут использоваться внутри обработчика для доступа к содержимому текущей и стековой областей диагностики.Изначально обе области диагностики возвращают одинаковый результат, поэтому можно получить информацию из текущей области диагностики о условии, которое активировало обработчик, пока вы не выполняете выражения внутри обработчика, которые изменяют его текущую область диагностики.
-
Однако выражения, выполняемые внутри обработчика, могут изменять текущую область диагностики, очищая и устанавливая ее содержимое в соответствии с обычными правилами (см. Как область диагностики очищается и заполняется).
Более надежный способ получения информации об условии, активирующем обработчик, — использовать стековую область диагностики, которую нельзя изменить выполняемыми внутри обработчика выражениями, за исключением
RESIGNAL. Сведения о том, когда устанавливается и очищается текущая область диагностики, см. в разделе 15.6.7.7, «Область диагностики MySQL».
Следующий пример показывает, как можно использовать GET STACKED
DIAGNOSTICS внутри обработчика для получения информации об обработанном исключении, даже после того, как текущая область диагностики была изменена выражениями обработчика.
Внутри хранимой процедуры p() мы пытаемся вставить два значения в таблицу, содержащую столбец TEXT NOT
NULL. Первое значение — строка, не являющаяся NULL, а второе — NULL. Столбец запрещает NULL значения, поэтому первая вставка проходит успешно, но вторая вызывает исключение. Процедура включает обработчик исключений, который отображает попытки вставки 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;
При активации обработчика копия текущей области диагностики помещается в стек области диагностики. Обработчик сначала отображает содержимое текущей и стековой областей диагностики, которые изначально совпадают:
+---------------------------------+-------+----------------------------+
| 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 |
+---------------------------------+-------+----------------------------+
Выражения, выполняемые после выражений GET
DIAGNOSTICS, могут сбросить текущую область диагностики. Выражения могут сбросить текущую область диагностики. Например, обработчик преобразует вставку NULL в вставку пустой строки и отображает результат. Новая вставка проходит успешно и очищает текущую область диагностики, но стековая область диагностики остается неизменной и по-прежнему содержит информацию об условии, которое активировало обработчик:
+----------------------------------------------+
| op |
+----------------------------------------------+
| mapped insert succeeded, current DA is empty |
+----------------------------------------------+
+--------------------------------+-------+----------------------------+
| op | errno | msg |
+--------------------------------+-------+----------------------------+
| stacked DA after mapped insert | 1048 | Column 'c1' cannot be null |
+--------------------------------+-------+----------------------------+
По окончании обработчика условий его текущая область диагностики извлекается из стека, а стековая область диагностики становится текущей областью диагностики в хранимой процедуре.
После возвращения процедуры в таблице содержатся две строки. Пустая строка — результат попытки вставки NULL, которая была преобразована во вставку пустой строки:
+----------+
| c1 |
+----------+
| string 1 |
| |
+----------+
© 2025 Oracle
Licensed under the GPLv2 License.