Ответ 1
ПОЛУЧЕНИЕ ДИАГНОСТИКИ доступно в 5.6.4
См http://dev.mysql.com/doc/refman/5.6/en/get-diagnostics.html
Я считаю, что в MySQL нет ничего доступного в 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
ПОЛУЧЕНИЕ ДИАГНОСТИКИ доступно в 5.6.4
См http://dev.mysql.com/doc/refman/5.6/en/get-diagnostics.html
Я считаю, что в MySQL нет ничего доступного в 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
Я делаю следующее обходное решение: используя SELECT для провоцирования ошибки. Например:
SELECT RAISE_ERROR_unable_to_update_basket;
Это приведет к следующему сообщению об ошибке (пример):
ERROR 1054 (42S22): Unknown column 'RAISE_ERROR_unable_to_update_basket' in 'field list'
Я завершу свой вызов хранимой процедуре в try {...} catch {...} и теперь могу обработать эту ошибку. Это, конечно же, будет работать только на провоцирование пользовательских сообщений об ошибках внутри хранимой процедуры и не будет обрабатывать любые ошибки SQL или базы данных, которые могут возникнуть (из-за записи с дубликат-ключ). В последнем случае вы можете обходить это, используя решение Johan.