Spec-Zone .ru
спецификации, руководства, описания, API

13.6.7.6. Правила контекста для Обработчиков

Сохраненная программа может включать обработчики, которые будут вызваны, когда определенные условия происходят в пределах программы. Применимость каждого обработчика зависит от его расположения в пределах определения программы и на условии или условиях, которые это обрабатывает:

Многократные обработчики могут быть объявлены в различных контекстах и с различными спецификами. Например, мог бы быть определенный обработчик кода ошибки MySQL во внешнем блоке, и генерал SQLWARNING обработчик во внутреннем блоке. Или могли бы быть обработчики для определенного кода ошибки MySQL и генерала SQLWARNING class в том же самом блоке.

Активируется ли обработчик, зависит не только от его собственного контекста и значения условия, но и от того, что присутствуют другие обработчики. Когда условие происходит в сохраненной программе, поиски сервера применимых обработчиков в текущем контексте (ток BEGIN ... END блок). Если нет никаких применимых обработчиков, поиск продолжается исходящий с обработчиками в каждом последовательном, содержащем контекст (блок). Когда сервер находит один или более применимые обработчики в данном контексте, он выбирает среди них базируемый при условии приоритет:

Одна импликация правил выбора обработчика - то, что, если многократные применимые обработчики происходят в различных контекстах, обработчики с самым локальным контекстом имеют приоритет по обработчикам во внешних контекстах, даже по тем для более особых условий.

Если нет никакого соответствующего обработчика, когда условие происходит, предпринятые меры зависят от class условия:

Следующие примеры демонстрируют, как 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'