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
В операторе SIGNAL значение condition_value указывает значение возвращаемой ошибки. Оно может быть 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.