15.6.7.7 Область диагностики MySQL
SQL-запросы генерируют диагностическую информацию, которая заполняет область диагностики. Стандартный SQL имеет стек областей диагностики, содержащий область диагностики для каждого вложенного контекста выполнения. Стандартный SQL также поддерживает GET STACKED
DIAGNOSTICS синтаксис для ссылки на вторую область диагностики во время выполнения обработчика условий.
Следующее обсуждение описывает структуру области диагностики в MySQL, элементы информации, распознаваемые 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 ...
Элементы информации области диагностики
Область диагностики содержит элементы информации о запросе и условии. Числовые элементы — это целые числа. Кодировка символов для символьных элементов — UTF-8. Ни один элемент не может быть NULL. Если элемент запроса или условия не установлен запросом, заполняющим область диагностики, его значение равно 0 или пустой строке в зависимости от типа данных элемента.
Часть информации о запросе в области диагностики содержит следующие элементы:
NUMBER: Целое число, указывающее количество областей условий, содержащих информацию.ROW_COUNT: Целое число, указывающее количество строк, затронутых запросом.ROW_COUNTимеет то же значение, что и функцияROW_COUNT()(см. Раздел 14.15, «Функции информации»).
Часть информации о условии в области диагностики содержит область условия для каждого условия. Области условий пронумерованы от 1 до значения элемента условия запроса NUMBER. Если NUMBER равно 0, областей условий нет.
Каждая область условия содержит элементы в следующем списке. Все элементы являются стандартными SQL, за исключением MYSQL_ERRNO, который является расширением MySQL. Определения применимы для условий, сгенерированных не сигналом (то есть запросом SIGNAL или RESIGNAL). Для условий, не являющихся сигналами, MySQL заполняет только те элементы условия, которые не описаны как всегда пустые. Влияние сигналов на область условия описано позже.
CLASS_ORIGIN: Строка, содержащая класс значенияRETURNED_SQLSTATE. Если значениеRETURNED_SQLSTATEначинается со значения класса, определенного в документе стандарта SQL ISO 9075-2 (раздел 24.1, SQLSTATE),CLASS_ORIGINимеет значение'ISO 9075'. В противном случае,CLASS_ORIGINимеет значение'MySQL'.SUBCLASS_ORIGIN: Строка, содержащая подкласс значенияRETURNED_SQLSTATE. ЕслиCLASS_ORIGINравно'ISO 9075'илиRETURNED_SQLSTATEзаканчивается на'000',SUBCLASS_ORIGINимеет значение'ISO 9075'. В противном случае,SUBCLASS_ORIGINимеет значение'MySQL'.RETURNED_SQLSTATE: Строка, указывающая значениеSQLSTATEдля условия.MESSAGE_TEXT: Строка, указывающая сообщение об ошибке для условия.MYSQL_ERRNO: Целое число, указывающее код ошибки MySQL для условия.CONSTRAINT_CATALOG,CONSTRAINT_SCHEMA,CONSTRAINT_NAME: Строки, указывающие каталог, схему и имя нарушенного ограничения. Они всегда пустые.CATALOG_NAME,SCHEMA_NAME,TABLE_NAME,COLUMN_NAME: Строки, указывающие каталог, схему, таблицу и столбец, связанные с условием. Они всегда пустые.CURSOR_NAME: Строка, указывающая имя курсора. Она всегда пустая.
Значения RETURNED_SQLSTATE, MESSAGE_TEXT и MYSQL_ERRNO для определенных ошибок см. в .
Если запрос SIGNAL (или RESIGNAL) заполняет область диагностики, его клаузула SET может присвоить любому элементу информации о условии, кроме RETURNED_SQLSTATE, любое значение, допустимое для типа данных элемента. SIGNAL также устанавливает значение RETURNED_SQLSTATE, но не напрямую в своей клаузе SET. Это значение берется из аргумента SQLSTATE запроса SIGNAL.
SIGNAL также устанавливает элементы информации о запросе. Он устанавливает NUMBER в 1. Он устанавливает ROW_COUNT в −1 для ошибок и в 0 в противном случае.
Как очищается и заполняется область диагностики
Недиагностические SQL-запросы автоматически заполняют область диагностики, а ее содержимое можно явно установить с помощью запросов SIGNAL и RESIGNAL. Область диагностики можно проверить с помощью запроса GET
DIAGNOSTICS для извлечения определенных элементов или с помощью SHOW WARNINGS или SHOW ERRORS для просмотра условий или ошибок.
SQL-запросы очищают и устанавливают область диагностики следующим образом:
-
Когда сервер начинает выполнение запроса после его парсинга, он очищает область диагностики для недиагностических запросов. Диагностические запросы не очищают область диагностики. К этим запросам относятся:
Если запрос вызывает условие, область диагностики очищается от условий, относящихся к предыдущим запросам. Исключение составляют условия, вызванные запросами
GET DIAGNOSTICSиRESIGNAL, которые добавляются в область диагностики без ее очистки.
Таким образом, даже запрос, который обычно не очищает область диагностики при запуске, очищает ее, если запрос вызывает условие.
Следующий пример демонстрирует влияние различных запросов на область диагностики, используя SHOW
WARNINGS для отображения информации о хранящихся там условиях.
Этот запрос DROP TABLE очищает область диагностики и заполняет ее при возникновении условия:
mysql> DROP TABLE IF EXISTS test.no_such_table;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> SHOW WARNINGS;
+-------+------+------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------+
| Note | 1051 | Unknown table 'test.no_such_table' |
+-------+------+------------------------------------+
1 row in set (0.00 sec)
Этот запрос SET генерирует ошибку, поэтому очищает и заполняет область диагностики:
mysql> SET @x = @@x;
ERROR 1193 (HY000): Unknown system variable 'x'
mysql> SHOW WARNINGS;
+-------+------+-----------------------------+
| Level | Code | Message |
+-------+------+-----------------------------+
| Error | 1193 | Unknown system variable 'x' |
+-------+------+-----------------------------+
1 row in set (0.00 sec)
Предыдущий запрос SET создал одно условие, поэтому 1 — единственный допустимый номер условия для GET
DIAGNOSTICS на данный момент. Следующий запрос использует номер условия 2, что приводит к предупреждению, которое добавляется в область диагностики без ее очистки:
mysql> GET DIAGNOSTICS CONDITION 2 @p = MESSAGE_TEXT;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+-------+------+------------------------------+
| Level | Code | Message |
+-------+------+------------------------------+
| Error | 1193 | Unknown system variable 'xx' |
| Error | 1753 | Invalid condition number |
+-------+------+------------------------------+
2 rows in set (0.00 sec)
Теперь в области диагностики есть два условия, поэтому тот же запрос GET DIAGNOSTICS выполняется успешно:
mysql> GET DIAGNOSTICS CONDITION 2 @p = MESSAGE_TEXT;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @p;
+--------------------------+
| @p |
+--------------------------+
| Invalid condition number |
+--------------------------+
1 row in set (0.01 sec)
Как работает стек области диагностики
При добавлении в стек области диагностики первая (текущая) область диагностики становится второй (сохраненной), а новая текущая область диагностики создается как ее копия. Области диагностики добавляются в стек и извлекаются из него в следующих ситуациях:
-
Выполнение хранимой программы
Добавление в стек происходит до выполнения программы, а извлечение — после. Если хранимая программа завершается во время выполнения обработчиков, может быть более одной области диагностики для извлечения; это происходит из-за исключения, для которого нет соответствующих обработчиков, или из-за
RETURNв обработчике.Любые предупреждения или ошибки в извлеченных областях диагностики затем добавляются в текущую область диагностики, за исключением триггеров, где добавляются только ошибки. Когда хранимая программа завершается, вызывающий элемент видит эти условия в своей текущей области диагностики.
-
Выполнение обработчика условия в хранимой программе
Когда добавление в стек происходит в результате активации обработчика условия, сохраненная область диагностики — это область, которая была текущей внутри хранимой программы перед добавлением. Новая текущая область диагностики — текущая область диагностики обработчика.
GET [CURRENT] DIAGNOSTICSиGET STACKED DIAGNOSTICSмогут использоваться внутри обработчика для доступа к содержимому текущих (обработчика) и сохраненных (хранимой программы) областей диагностики. Изначально они возвращают одинаковый результат, но запросы, выполняемые внутри обработчика, изменяют текущую область диагностики, очищая и устанавливая ее содержимое в соответствии с обычными правилами (см. Как очищается и заполняется область диагностики). Сохраненная область диагностики не может быть изменена запросами, выполняемыми внутри обработчика, за исключениемRESIGNAL.Если обработчик выполняется успешно, текущая (обработчика) область диагностики извлекается, а сохраненная (хранимой программы) область диагностики снова становится текущей. Условия, добавленные в область диагностики обработчика во время выполнения обработчика, добавляются в текущую область диагностики.
-
Выполнение
RESIGNALЗапрос
RESIGNALпередает информацию об ошибках, доступную во время выполнения обработчика условия в составном запросе внутри хранимой программы. ЗапросRESIGNALможет изменить часть или всю информацию перед передачей, изменив стек диагностики, как описано в Раздел 15.6.7.4, «Запрос RESIGNAL».
Системные переменные, связанные с областью диагностики
Некоторые системные переменные управляют или связаны с некоторыми аспектами области диагностики:
max_error_countуправляет количеством областей условий в области диагностики. Если возникает больше условий, чем это, MySQL без сообщений отбрасывает информацию для избыточных условий. (Условия, добавленные с помощьюRESIGNAL, всегда добавляются, при этом более старые условия отбрасываются по мере необходимости для освобождения места.)warning_countуказывает количество возникших условий. Это включает ошибки, предупреждения и заметки. Обычно,NUMBERиwarning_countсовпадают. Однако, по мере превышения количества сгенерированных условийmax_error_count, значениеwarning_countпродолжает расти, в то время какNUMBERостается ограниченнымmax_error_count, так как в области диагностики не хранятся дополнительные условия.error_countуказывает количество возникших ошибок. Это значение включает условия «не найдено» и исключения, но не предупреждения и заметки. Как иwarning_count, его значение может превышатьmax_error_count.Если системная переменная
sql_notesустановлена в 0, заметки не хранятся и не увеличивают значениеwarning_count.
Пример: Если max_error_count равно 10, область диагностики может содержать максимум 10 областей условий. Предположим, что запрос вызывает 20 условий, 12 из которых являются ошибками. В этом случае область диагностики содержит первые 10 условий, NUMBER равно 10, warning_count равно 20, а error_count равно 12.
Изменения значения max_error_count не влияют до следующей попытки модификации области диагностики. Если область диагностики содержит 10 областей условий, а max_error_count установлено в 5, это не оказывает немедленного влияния на размер или содержимое области диагностики.
© 2025 Oracle
Licensed under the GPLv2 License.