Используя пример г-на Кассного, вот мой лучший подход к обнаружению конкретных ошибок:
Идея состоит в том, чтобы использовать переменную tvariable для перехвата простого сообщения об ошибке, затем вы можете перехватить состояния sql, которые, по вашему мнению, могут произойти, сохранить пользовательские сообщения в вашей переменной:
DELIMITER $$
DROP PROCEDURE IF EXISTS prc_work $$
CREATE PROCEDURE prc_work ()
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '23000'
BEGIN
SET @prc_work_error = 'Repeated key';
ROLLBACK TO sp_prc_work;
END;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET @prc_work_error = 'Unknown error';
ROLLBACK TO sp_prc_work;
END;
START TRANSACTION;
SAVEPOINT sp_prc_work;
INSERT into test (id, name) VALUES (1, 'SomeText');
COMMIT;
END $$
DELIMITER ;
Затем вы просто делаете обычный вызов и делаете оператор выбора для переменной, например:
call prc_work(); select @prc_work_error;
Возвращается либо NULL, если ошибки нет, либо сообщение об ошибке в случае ошибки. Если вам нужно постоянное сообщение об ошибке, вы можете создать таблицу для его хранения.
Это утомительно и не очень гибко, поскольку требует сегмента DECLARE EXIT HANDLER для каждого кода состояния, который вы хотите перехватить, он также не отображает подробные сообщения об ошибках, но, эй, он работает.