Обработка ошибок хранимых процедур MySQL - PullRequest
13 голосов
/ 14 октября 2011

Я полагаю, что в настоящее время в MySQL нет ничего, что позволяло бы получить доступ к SQLSTATE последнего выполненного оператора в хранимой процедуре MySQL.Это означает, что когда универсальный SQLException вызывается в хранимой процедуре, трудно / невозможно определить точную природу ошибки.

Есть ли у кого-нибудь обходной путь для получения SQLSTATE ошибки вхранимая процедура MySQL, которая не включает объявление обработчика для каждого возможного SQLSTATE?

Например - представьте, что я пытаюсь вернуть error_status, выходящий за рамки общего "SQLException произошло где-то в этом BEGIN....END блоке"в следующем:

DELIMITER $$

CREATE PROCEDURE `myProcedure`(OUT o_error_status varchar(50))
MY_BLOCK: BEGIN

 DECLARE EXIT handler for 1062 set o_error_status := "Duplicate entry in table";
 DECLARE EXIT handler for 1048 set o_error_status := "Trying to populate a non-null column with null value"; 
-- declare handlers ad nauseum here....

 DECLARE EXIT handler for sqlexception set o_error_status:= "Generic SQLException. You'll just have to figure out the SQLSTATE yourself...." ;

-- Procedure logic that might error to follow here...

END MY_BLOCK$$

Любые советы?

PS Я использую MySQL 5.1.49

Ответы [ 3 ]

9 голосов
/ 14 октября 2011

Я считаю, что в настоящее время в MySQL нет ничего, что позволяло бы получить доступ к SQLSTATE последнего выполненного оператора в хранимой процедуре MySQL.Это означает, что ... трудно / невозможно определить точную природу ошибки.

К счастью, это не так.

SHOW ERRORS LIMIT 1   -- for SQL-state > 2
SHOW WARNINGS LIMIT 1 -- for SQL-state 1,2

Будет отображаться последняя ошибка или предупреждение.

Чтобы избежать перечисления каждой ошибки, вы можете обработать класс ошибок SQL, например:

SQLWARNING является сокращением для класса значений SQLSTATE, начинающихся с '01'.

NOT FOUND является сокращением для класса значений SQLSTATE, начинающихся с '02'.Это относится только к контексту курсоров и используется для управления тем, что происходит, когда курсор достигает конца набора данных.Если больше нет доступных строк, возникает условие «Нет данных» со значением SQLSTATE 02000. Чтобы обнаружить это условие, вы можете установить для него обработчик (или для условия «НЕ НАЙДЕНО»).Пример показан в Разделе 12.7.5, «Курсоры».Это условие также возникает для операторов SELECT ... INTO var_list, которые не получают строк.

SQLEXCEPTION - сокращение от класса значений SQLSTATE, которые не начинаются с '00', '01' или '02'.

Таким образом, чтобы обработать исключение, вам нужно только сделать:

DECLARE EXIT HANDLER FOR SQLSTATE SQLEXCEPTION .....;

Ссылки:
http://dev.mysql.com/doc/refman/5.5/en/signal.html
http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html

8 голосов
/ 19 января 2012

ПОЛУЧИТЬ ДИАГНОСТИКУ можно в 5.6.4

См. http://dev.mysql.com/doc/refman/5.6/en/get-diagnostics.html

0 голосов
/ 14 октября 2011

Я делаю следующий обходной путь: используя SELECT, чтобы вызвать ошибку.Например:

SELECT RAISE_ERROR_unable_to_update_basket;

Это приведет к следующему сообщению об ошибке (пример):

ERROR 1054 (42S22): Unknown column 'RAISE_ERROR_unable_to_update_basket' in 'field list'

Я завершаю вызов хранимой процедуры при попытке {...}catch {...} и теперь может обработать эту ошибку.Это, конечно, будет работать только для провоцирования пользовательских сообщений об ошибках изнутри вашей хранимой процедуры и не будет обрабатывать любые ошибки SQL или базы данных, которые могут возникнуть (из-за ввода дубликата ключа).В последнем случае вы можете обойти это, используя решение Йохана.

...