Spec-Zone .ru
спецификации, руководства, описания, API
|
DECLAREhandler_action
HANDLER FORcondition_value
[,condition_value
] ...statement
handler_action
: CONTINUE | EXIT | UNDOcondition_value
:mysql_error_code
| SQLSTATE [VALUE]sqlstate_value
|condition_name
| SQLWARNING | NOT FOUND | SQLEXCEPTION
DECLARE ... HANDLER
оператор определяет обработчик, который имеет дело с одним
или более условиями. Если одно из этих условий происходит, указанное statement
выполняется. statement
может быть простой оператор такой как SET
,
или составной оператор, записанный, используя var_name
= value
BEGIN
и END
(см. Раздел
13.6.1,"BEGIN ... END
Синтаксис составного оператора").
Объявления обработчика должны появиться после объявлений условия или переменной.
handler_action
значение указывает на то, какое меры обработчик
предпринимает после выполнения оператора обработчика:
CONTINUE
: Выполнение текущей программы продолжается.
EXIT
: Выполнение завершается для BEGIN ... END
составной оператор, в котором объявляется обработчик. Это -
истина, даже если условие происходит во внутреннем блоке.
UNDO
: Не поддерживаемый.
condition_value
для DECLARE ... HANDLER
указывает на особое условие или class условий, который
активирует обработчик:
Код ошибки MySQL (число) или значение SQLSTATE (5-символьный строковый литерал).
Недопустимо использовать код ошибки MySQL 0 или значения SQLSTATE, которые начинаются '00'
, потому что те указывают на успех, а не состояние ошибки. Для списка
кодов ошибки MySQL и значений SQLSTATE, см. Раздел C.3,
"Коды ошибки сервера и сообщения".
Имя условия, ранее определенное с DECLARE ... CONDITION
. Имя условия может быть связано с кодом ошибки
MySQL или значением SQLSTATE. См. Раздел 13.6.7.1,"DECLARE ... CONDITION
Синтаксис".
SQLWARNING
сокращение для class значений SQLSTATE,
которые начинаются '01'
.
NOT FOUND
сокращение для class значений SQLSTATE,
которые начинаются '02'
. Это релевантно в пределах контекста курсоров и
используется, чтобы управлять тем, что происходит, когда курсор достигает конца набора данных. Если
больше строк не доступно, Никакое условие Данных не происходит со значением SQLSTATE '02000'
. Чтобы обнаружить это условие, можно установить обработчик для
этого (или для a NOT FOUND
условие). Для примера см. Раздел
13.6.6, "Курсоры". Это условие также происходит для SELECT ...
INTO
операторы, которые не получают строк.
var_list
SQLEXCEPTION
сокращение для class значений SQLSTATE,
которые не начинаются '00'
, '01'
, или '02'
.
Для получения информации о том, как сервер выбирает обработчики, когда условие происходит, см. Раздел 13.6.7.6, "Правила контекста для Обработчиков".
Если условие происходит, для которого не был объявлен никакой обработчик, предпринятые меры зависят от условия class:
Для SQLEXCEPTION
условия, сохраненная программа
завершается в операторе, который повысил условие, как будто было EXIT
обработчик. Если программу вызвала другая сохраненная программа, программа вызова обрабатывает условие,
используя правила выбора обработчика, которым применяются к его собственные обработчики.
Для SQLWARNING
условия, программа продолжает
выполняться, как будто были a CONTINUE
обработчик.
Для NOT FOUND
условия, если условие обычно повышалось,
действие, CONTINUE
. Если это было повышено SIGNAL
или RESIGNAL
, действие EXIT
.
Следующий пример использует обработчик для SQLSTATE '23000'
, который происходит для
двойной ключевой ошибки:
mysql>CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));
Query OK, 0 rows affected (0.00 sec)mysql>delimiter //
mysql>CREATE PROCEDURE handlerdemo ()
->BEGIN
->DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
->SET @x = 1;
->INSERT INTO test.t VALUES (1);
->SET @x = 2;
->INSERT INTO test.t VALUES (1);
->SET @x = 3;
->END;
->//
Query OK, 0 rows affected (0.00 sec)mysql>CALL handlerdemo()//
Query OK, 0 rows affected (0.00 sec)mysql>SELECT @x//
+------+ | @x | +------+ | 3 | +------+ 1 row in set (0.00 sec)
Заметьте это @x
3
после того, как процедура
выполняется, который показывает, что выполнение, продолжаемое до конца процедуры после ошибки, произошло. Если
DECLARE ... HANDLER
оператор не присутствовал, MySQL предпримет меры значения
по умолчанию (EXIT
) после второго INSERT
отказавший из-за PRIMARY KEY
ограничение,
и SELECT @x
возвратился бы 2
.
Чтобы проигнорировать условие, объявите a CONTINUE
обработчик для этого и партнер
это с пустым блоком. Например:
DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;
Контекст блочной метки не включает код для обработчиков, объявленных в пределах блока. Поэтому, оператор,
связанный с обработчиком, не может использовать ITERATE
или LEAVE
обратиться к меткам для блоков, которые включают объявление
обработчика. Рассмотрите следующий пример, где REPEAT
у блока есть метка retry
:
CREATE PROCEDURE p ()BEGIN DECLARE i INT DEFAULT 3; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN ITERATE retry; # illegal END; IF i < 0 THEN LEAVE retry; # legal END IF; SET i = i - 1; END; UNTIL FALSE END REPEAT;END;
retry
метка находится в контексте для IF
оператор в пределах блока. Это не находится в контексте для CONTINUE
обработчик, таким образом, ссылка там недопустима и приводит к ошибке:
ERROR 1308 (42000): LEAVE with no matching label: retry
Чтобы избежать ссылок на внешние метки в обработчиках, используйте одну из этих стратегий:
Чтобы оставить блок, используйте EXIT
обработчик. Если
никакая блочная уборка не требуется, BEGIN ... END
корпус обработчика может быть пустым:
DECLARE EXIT HANDLER FOR SQLWARNING BEGIN END;
Иначе, поместите операторы уборки в корпус обработчика:
DECLARE EXIT HANDLER FOR SQLWARNING BEGIN block
cleanup statements
END;
Чтобы продолжать выполнение, установите переменную состояния в a CONTINUE
обработчик, который может быть проверен в блоке включения, чтобы
определить, был ли обработчик вызван. Следующий пример использует переменную done
с этой целью:
CREATE PROCEDURE p ()BEGIN DECLARE i INT DEFAULT 3; DECLARE done INT DEFAULT FALSE; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN SET done = TRUE; END; IF done OR i < 0 THEN LEAVE retry; END IF; SET i = i - 1; END; UNTIL FALSE END REPEAT;END;