15.6.7.5 Оператор SIGNAL
SIGNAL condition_value
[SET signal_information_item
[, signal_information_item] ...]
condition_value: {
SQLSTATE [VALUE] sqlstate_value
| condition_name
}
signal_information_item:
condition_information_item_name = simple_value_specification
condition_information_item_name: {
CLASS_ORIGIN
| SUBCLASS_ORIGIN
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
}
condition_name, simple_value_specification:
(see following discussion)
SIGNAL — это способ “возврата” ошибки. SIGNAL предоставляет информацию об ошибке обработчику, внешней части приложения или клиенту. Также он предоставляет контроль над характеристиками ошибки (номер ошибки, SQLSTATE значение, сообщение). Без SIGNAL необходимо прибегать к обходным путям, например, преднамеренно обращаться к несуществующей таблице, чтобы заставить рутину вернуть ошибку.
Для выполнения оператора SIGNAL привилегии не требуются.
Для извлечения информации из области диагностики используйте оператор GET DIAGNOSTICS (см. Раздел 15.6.7.3, «Оператор GET DIAGNOSTICS»). С информацией об области диагностики можно ознакомиться в Разделе 15.6.7.7, «Область диагностики MySQL».
Обзор оператора SIGNAL
condition_value в операторе SIGNAL указывает значение возвращаемой ошибки. Это может быть SQLSTATE значение (строковый литерал длиной 5 символов) или condition_name, которое ссылается на именованное условие, ранее определенное с помощью DECLARE ...
CONDITION (см. Раздел 15.6.7.1, «Оператор DECLARE ... CONDITION»).
Значение SQLSTATE может указывать на ошибки, предупреждения или “не найден”. Первые два символа значения указывают на класс ошибки, как обсуждается в Элементы информации о состоянии сигнала. Некоторые значения сигналов приводят к завершению оператора; см. Влияние сигналов на обработчики, курсоры и операторы.
Значение SQLSTATE для оператора SIGNAL не должно начинаться с '00', поскольку такие значения указывают на успех и не подходят для сигнализации об ошибке. Это верно, независимо от того, задано ли SQLSTATE значение напрямую в операторе SIGNAL или в именованном условии, на которое ссылается оператор. Если значение некорректно, возникает ошибка Bad SQLSTATE.
Для сигнализации об общем SQLSTATE значении используйте '45000', что означает “необработанное пользовательское исключение”.
Оператор SIGNAL необязательно включает в себя предложение SET, которое содержит несколько элементов сигнала в списке condition_information_item_name = simple_value_specification, разделенных запятыми.
Каждый condition_information_item_name может быть указан только один раз в предложении SET. В противном случае возникает ошибка Duplicate condition information
item.
Допустимые simple_value_specification идентификаторы могут быть заданы с помощью параметров хранимых процедур или функций, локальных переменных хранимых программ, объявленных с помощью DECLARE, пользовательских переменных, системных переменных или литералов. Литерал символьного типа может включать _charset-префикс.
С информацией о допустимых значениях condition_information_item_name можно ознакомиться в Элементы информации о состоянии сигнала.
Следующая процедура сигнализирует об ошибке или предупреждении в зависимости от значения pval, ее входного параметра:
CREATE PROCEDURE p (pval INT)
BEGIN
DECLARE specialty CONDITION FOR SQLSTATE '45000';
IF pval = 0 THEN
SIGNAL SQLSTATE '01000';
ELSEIF pval = 1 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'An error occurred';
ELSEIF pval = 2 THEN
SIGNAL specialty
SET MESSAGE_TEXT = 'An error occurred';
ELSE
SIGNAL SQLSTATE '01000'
SET MESSAGE_TEXT = 'A warning occurred', MYSQL_ERRNO = 1000;
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'An error occurred', MYSQL_ERRNO = 1001;
END IF;
END;
Если pval равно 0, p() сигнализирует о предупреждении, так как SQLSTATE значения, начинающиеся с '01', относятся к сигналам класса предупреждений. Предупреждение не завершает процедуру и может быть отображено с помощью SHOW
WARNINGS после возврата процедуры.
Если pval равно 1, p() сигнализирует об ошибке и устанавливает элемент информации о состоянии условия MESSAGE_TEXT. Ошибка завершает процедуру, и текст возвращается с информацией об ошибке.
Если pval равно 2, сигнализируется та же ошибка, хотя значение SQLSTATE в данном случае задается с помощью именованного условия.
Если pval — любое другое значение, p() сначала сигнализирует о предупреждении и устанавливает текстовые элементы информации о состоянии и номер ошибки. Это предупреждение не завершает процедуру, поэтому выполнение продолжается, и p() затем сигнализирует об ошибке. Ошибка завершает процедуру. Текстовый элемент и номер ошибки, установленные предупреждением, заменяются значениями, установленными ошибкой, которые возвращаются с информацией об ошибке.
Оператор SIGNAL обычно используется в хранимых программах, но это расширение MySQL, позволяющее использовать его вне контекста обработчика. Например, если вы вызываете программу-клиент mysql, вы можете ввести любой из этих операторов в командной строке:
SIGNAL SQLSTATE '77777';
CREATE TRIGGER t_bi BEFORE INSERT ON t
FOR EACH ROW SIGNAL SQLSTATE '77777';
CREATE EVENT e ON SCHEDULE EVERY 1 SECOND
DO SIGNAL SQLSTATE '77777';
Оператор SIGNAL выполняется по следующим правилам:
Если оператор SIGNAL указывает конкретное SQLSTATE значение, это значение используется для сигнализации указанного условия. Пример:
CREATE PROCEDURE p (divisor INT)
BEGIN
IF divisor = 0 THEN
SIGNAL SQLSTATE '22012';
END IF;
END;
Если оператор SIGNAL использует именованное условие, это условие должно быть объявлено в каком-либо области действия, которое относится к оператору SIGNAL, и должно быть определено с помощью значения SQLSTATE, а не номера ошибки MySQL. Пример:
CREATE PROCEDURE p (divisor INT)
BEGIN
DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
IF divisor = 0 THEN
SIGNAL divide_by_zero;
END IF;
END;
Если именованное условие не существует в области действия оператора SIGNAL, возникает ошибка Undefined CONDITION.
Если оператор SIGNAL ссылается на именованное условие, которое определено с помощью номера ошибки MySQL, а не значения SQLSTATE, возникает ошибка SIGNAL/RESIGNAL can only use a CONDITION defined with
SQLSTATE. Следующие операторы вызывают эту ошибку, так как именованное условие связано с номером ошибки MySQL:
DECLARE no_such_table CONDITION FOR 1051;
SIGNAL no_such_table;
Если условие с заданным именем объявлено несколько раз в разных областях действия, применяется объявление с самой локальной областью действия. Рассмотрим следующую процедуру:
CREATE PROCEDURE p (divisor INT)
BEGIN
DECLARE my_error CONDITION FOR SQLSTATE '45000';
IF divisor = 0 THEN
BEGIN
DECLARE my_error CONDITION FOR SQLSTATE '22012';
SIGNAL my_error;
END;
END IF;
SIGNAL my_error;
END;
Если divisor равно 0, выполняется первый оператор SIGNAL. Применяется объявление условия my_error с наибольшей локальностью, что вызывает ошибку SQLSTATE '22012'.
Если divisor не равно 0, выполняется второй оператор SIGNAL. Применяется объявление условия my_error с наибольшей глобальностью, что вызывает ошибку SQLSTATE '45000'.
С информацией о том, как сервер выбирает обработчики, когда возникает условие, см. Раздел 15.6.7.6, «Правила области действия обработчиков».
Сигналы могут быть вызваны в обработчиках исключений:
CREATE PROCEDURE p ()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SIGNAL SQLSTATE VALUE '99999'
SET MESSAGE_TEXT = 'An error occurred';
END;
DROP TABLE no_such_table;
END;
CALL p() достигает оператора DROP TABLE. Таблицы с именем no_such_table нет, поэтому активируется обработчик ошибок. Обработчик ошибок уничтожает исходную ошибку (“такой таблицы нет”) и создает новую ошибку с SQLSTATE '99999' и сообщением An error occurred.
Элементы информации о состоянии условия сигнала
В следующей таблице перечислены имена элементов информации о состоянии области диагностики, которые можно установить в операторе SIGNAL (или RESIGNAL). Все элементы являются стандартными SQL, за исключением MYSQL_ERRNO, который является расширением MySQL. Дополнительную информацию об этих элементах см. в Разделе 15.6.7.7, «Область диагностики MySQL».
Item Name Definition
--------- ----------
CLASS_ORIGIN VARCHAR(64)
SUBCLASS_ORIGIN VARCHAR(64)
CONSTRAINT_CATALOG VARCHAR(64)
CONSTRAINT_SCHEMA VARCHAR(64)
CONSTRAINT_NAME VARCHAR(64)
CATALOG_NAME VARCHAR(64)
SCHEMA_NAME VARCHAR(64)
TABLE_NAME VARCHAR(64)
COLUMN_NAME VARCHAR(64)
CURSOR_NAME VARCHAR(64)
MESSAGE_TEXT VARCHAR(128)
MYSQL_ERRNO SMALLINT UNSIGNED
Кодировка символов для символьных элементов — UTF-8.
Не допускается присваивать NULL элементу информации о состоянии в операторе SIGNAL.
Оператор SIGNAL всегда указывает значение SQLSTATE, либо непосредственно, либо косвенно, ссылаясь на именованное условие, определённое с помощью значения SQLSTATE. Первые два символа значения SQLSTATE — это его класс, а класс определяет значение по умолчанию для элементов информации о состоянии:
-
Класс =
'00'(успех)Недопустимо. Значения
SQLSTATE, начинающиеся с'00', указывают на успех и не являются допустимыми для оператораSIGNAL. -
Класс =
'01'(предупреждение)MESSAGE_TEXT = 'Unhandled user-defined warning condition'; MYSQL_ERRNO =
-
Класс =
'02'(не найдено)MESSAGE_TEXT = 'Unhandled user-defined not found condition'; MYSQL_ERRNO =
-
Класс >
'02'(исключение)MESSAGE_TEXT = 'Unhandled user-defined exception condition'; MYSQL_ERRNO =
Для допустимых классов остальные элементы информации о состоянии устанавливаются следующим образом:
CLASS_ORIGIN = SUBCLASS_ORIGIN = '';
CONSTRAINT_CATALOG = CONSTRAINT_SCHEMA = CONSTRAINT_NAME = '';
CATALOG_NAME = SCHEMA_NAME = TABLE_NAME = COLUMN_NAME = '';
CURSOR_NAME = '';
Значения ошибок, доступные после выполнения оператора SIGNAL, это значение SQLSTATE, поднятое оператором SIGNAL, и элементы MESSAGE_TEXT и MYSQL_ERRNO. Эти значения доступны из API C:
возвращает значение
SQLSTATE.возвращает значение
MYSQL_ERRNO.возвращает значение
MESSAGE_TEXT.
На уровне SQL вывод из операторов SHOW
WARNINGS и SHOW
ERRORS указывает на значения MYSQL_ERRNO и MESSAGE_TEXT в столбцах Code и Message соответственно.
Для получения информации из области диагностики используйте оператор GET DIAGNOSTICS (см. Раздел 15.6.7.3, «Оператор GET DIAGNOSTICS»). Для получения информации об области диагностики см. Раздел 15.6.7.7, «Область диагностики MySQL».
Воздействие сигналов на обработчики, курсоры и операторы
Сигналы оказывают различное влияние на выполнение операторов в зависимости от класса сигнала. Класс определяет, насколько серьёзной является ошибка. MySQL игнорирует значение системной переменной sql_mode; в частности, строгий SQL-режим не имеет значения. MySQL также игнорирует IGNORE: Целью оператора SIGNAL является явное поднятие пользователем генерируемой ошибки, поэтому сигнал никогда не игнорируется.
В следующих описаниях “необработанное” означает, что не было определено обработчика для сигнализируемого значения SQLSTATE с помощью оператора DECLARE ...
HANDLER.
-
Класс =
'00'(успех)Недопустимо. Значения
SQLSTATE, начинающиеся с'00', указывают на успех и не являются допустимыми для оператораSIGNAL. -
Класс =
'01'(предупреждение)Значение системной переменной
warning_countувеличивается. ОператорSHOW WARNINGSотображает сигнал. ОбработчикиSQLWARNINGперехватывают сигнал.Предупреждения не могут быть возвращены из хранимых функций, так как оператор
RETURN, который заставляет функцию вернуть значение, очищает область диагностики. Таким образом, оператор удаляет любые предупреждения, которые могли там присутствовать (и сбрасываетwarning_countдо 0). -
Класс =
'02'(не найдено)Обработчики
NOT FOUNDперехватывают сигнал. Курсоры не затрагиваются. Если сигнал не обрабатывается в хранимой функции, операторы завершаются. -
Класс >
'02'(исключение)Обработчики
SQLEXCEPTIONперехватывают сигнал. Если сигнал не обрабатывается в хранимой функции, операторы завершаются. -
Класс =
'40'Обращается как обычное исключение.
© 2025 Oracle
Licensed under the GPLv2 License.