Spec-Zone .ru
спецификации, руководства, описания, API
|
Сохраненная программа может включать обработчики, которые будут вызваны, когда определенные условия происходят в пределах программы. Применимость каждого обработчика зависит от его расположения в пределах определения программы и на условии или условиях, которые это обрабатывает:
Обработчик объявляется в a BEGIN ... END
блок находится в контексте только для SQL-операторов после
объявлений обработчика в блоке. Если сам обработчик повышает условие, он не может обработать то условие,
ни могут любые другие обработчики, объявленные в блоке. В следующем примере, обработчиках H1
и H2
находятся в контексте для условий,
повышенных операторами stmt1
и stmt2
.
Но ни один H1
ни H2
находятся в контексте для
условий, повышенных в теле H1
или H2
.
BEGIN -- outer block DECLARE EXIT HANDLER FOR ...; -- handler H1 DECLARE EXIT HANDLER FOR ...; -- handler H2stmt1
;stmt2
;END;
Обработчик находится в контексте только для блока, в котором это объявляется, и не
может быть активировано для условий, происходящих вне того блока. В следующем примере, обработчике H1
находится в контексте для stmt1
во внутреннем блоке, но не для stmt2
во внешнем блоке:
BEGIN -- outer block BEGIN -- inner block DECLARE EXIT HANDLER FOR ...; -- handler H1stmt1
; END;stmt2
;END;
Обработчик может быть определенным или общим. Определенный обработчик для кода
ошибки MySQL, SQLSTATE
значение, или имя условия. Общий обработчик для
условия в SQLWARNING
, SQLEXCEPTION
, или NOT FOUND
class. Специфика условия связывается с приоритетом условия, как
описано позже.
Многократные обработчики могут быть объявлены в различных контекстах и с различными спецификами. Например, мог
бы быть определенный обработчик кода ошибки MySQL во внешнем блоке, и генерал SQLWARNING
обработчик во внутреннем блоке. Или могли бы быть обработчики для
определенного кода ошибки MySQL и генерала SQLWARNING
class в том же самом блоке.
Активируется ли обработчик, зависит не только от его собственного контекста и значения условия, но и от того,
что присутствуют другие обработчики. Когда условие происходит в сохраненной программе, поиски сервера применимых
обработчиков в текущем контексте (ток BEGIN ... END
блок). Если нет никаких применимых обработчиков, поиск
продолжается исходящий с обработчиками в каждом последовательном, содержащем контекст (блок). Когда сервер
находит один или более применимые обработчики в данном контексте, он выбирает среди них базируемый при условии
приоритет:
Обработчик кода ошибки MySQL имеет приоритет по SQLSTATE
обработчик значения.
SQLSTATE
обработчик значения имеет приоритет по общему
SQLWARNING
, SQLEXCEPTION
, или NOT FOUND
обработчики.
SQLEXCEPTION
обработчик имеет приоритет по SQLWARNING
обработчик.
Приоритет NOT FOUND
зависит от того, как условие
повышается:
Обычно, условие в NOT FOUND
class может
быть обработан SQLWARNING
или NOT
FOUND
обработчик, с SQLWARNING
обработчик, имеющий
приоритет, если оба присутствуют. Нормальное возникновение NOT
FOUND
имеет место, когда курсор, используемый, чтобы выбрать ряд строк, достигает
конца набора данных, или для экземпляров SELECT ... INTO
так, что var_list
WHERE
пункт не находит строк.
Если a NOT FOUND
условие повышается a SIGNAL
(или RESIGNAL
) оператор, условие может быть обработано a NOT FOUND
обработчик, но не SQLWARNING
обработчик.
Возможно иметь несколько применимых обработчиков с тем же самым приоритетом. Например, оператор мог генерировать многократные предупреждения с различными кодами ошибки, для каждого из которых существует специфичный для ошибки обработчик. В этом случае, выбор которого обработчик сервер активируется, неопределенно, и может измениться в зависимости от обстоятельств, при которых происходит условие.
Одна импликация правил выбора обработчика - то, что, если многократные применимые обработчики происходят в различных контекстах, обработчики с самым локальным контекстом имеют приоритет по обработчикам во внешних контекстах, даже по тем для более особых условий.
Если нет никакого соответствующего обработчика, когда условие происходит, предпринятые меры зависят от class условия:
Для SQLEXCEPTION
условия, сохраненная программа
завершается в операторе, который повысил условие, как будто было EXIT
обработчик. Если программу вызвала другая сохраненная программа, программа вызова обрабатывает условие,
используя правила выбора обработчика, которым применяются к его собственные обработчики.
Для SQLWARNING
условия, программа продолжает
выполняться, как будто были a CONTINUE
обработчик.
Для NOT FOUND
условия, если условие обычно повышалось,
действие, CONTINUE
. Если это было повышено SIGNAL
или RESIGNAL
, действие EXIT
.
Следующие примеры демонстрируют, как MySQL применяет правила выбора обработчика.
Эта процедура содержит два обработчика, один для определенного SQLSTATE
значение
('42S02'
) это происходит для попыток отбросить несуществующую таблицу, и один для
генерала SQLEXCEPTION
class:
CREATE PROCEDURE p1()BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; DROP TABLE test.t;END;
Оба обработчика объявляются в том же самом блоке и имеют тот же самый контекст. Однако, SQLSTATE
обработчики имеют приоритет SQLEXCEPTION
обработчики, так если таблица t
является несуществующим, DROP TABLE
оператор повышает условие, которое активируется SQLSTATE
обработчик:
mysql> CALL p1();
+--------------------------------+| msg |+--------------------------------+| SQLSTATE handler was activated |+--------------------------------+
Эта процедура содержит те же самые два обработчика. Но на сей раз, DROP TABLE
оператор и SQLEXCEPTION
обработчик
находится во внутреннем блоке относительно SQLSTATE
обработчик:
CREATE PROCEDURE p2()BEGIN -- outer block DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; BEGIN -- inner block DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; DROP TABLE test.t; -- occurs within inner block END;END;
В этом случае обработчик, который более локален туда, где условие происходит, имеет приоритет. SQLEXCEPTION
обработчик активируется, даже при том, что это является более общим чем
SQLSTATE
обработчик:
mysql> CALL p2();
+------------------------------------+| msg |+------------------------------------+| SQLEXCEPTION handler was activated |+------------------------------------+
В этой процедуре один из обработчиков объявляется в блоке, внутреннем к контексту DROP TABLE
оператор:
CREATE PROCEDURE p3()BEGIN -- outer block DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; BEGIN -- inner block DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; END; DROP TABLE test.t; -- occurs within outer blockEND;
Только SQLEXCEPTION
обработчик применяется, потому что другой не находится в
контексте для условия, повышенного DROP TABLE
:
mysql> CALL p3();
+------------------------------------+| msg |+------------------------------------+| SQLEXCEPTION handler was activated |+------------------------------------+
В этой процедуре оба обработчика объявляются в блоке, внутреннем к контексту DROP TABLE
оператор:
CREATE PROCEDURE p4()BEGIN -- outer block BEGIN -- inner block DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; END; DROP TABLE test.t; -- occurs within outer blockEND;
Никакой обработчик не применяется, потому что они не находятся в контексте для DROP TABLE
. Условие, повышенное оператором, идет необработанное и завершает
процедуру с ошибкой:
mysql> CALL p4();
ERROR 1051 (42S02): Unknown table 'test.t'