13.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 (см. Раздел 13.6.7.3, «Оператор GET DIAGNOSTICS»). Сведения об области диагностики см. в Разделе 13.6.7.7, «Область диагностики MySQL».
Обзор оператора SIGNAL
Значение condition_value в операторе SIGNAL указывает возвращаемое значение ошибки. Оно может быть SQLSTATE значением (строковая литерал из 5 символов) или condition_name, ссылающимся на именованное условие, ранее определённое с помощью DECLARE ...
CONDITION (см. Раздел 13.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'.
Сведения о том, как сервер выбирает обработчики при возникновении условия, см. в Разделе 13.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. Более подробную информацию об этих элементах см. в Разделе 13.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 (см. Раздел 13.6.7.3, «Оператор GET DIAGNOSTICS»). Сведения об области диагностики см. в Разделе 13.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.