Spec-Zone.ru › MySQL 5.7

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

  • Элементы информации о состоянии сигнала

  • Воздействие сигналов на обработчики, курсоры и операторы

Обзор оператора 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.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/signal.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API