Невозможно обработать исключение в функции MYSQL - PullRequest
0 голосов
/ 22 февраля 2020

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

Я пытаюсь вернуть 0, если выполнение инструкции вставки завершается неудачно, и 1 в противном случае. Исключение повышается, а не обрабатывается. Где я иду не так?


    CREATE DEFINER=`myusr`@`localhost` FUNCTION `func1`(p1 varchar(50), p2 varchar(6)) RETURNS int(1)
        READS SQL DATA
        DETERMINISTIC
    BEGIN
        DECLARE EXP DATETIME;
        DECLARE RINT INT(1);
        DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
        BEGIN
           RETURN  0;
        END;
        SET exp = DATE_ADD(NOW(), INTERVAL 15 MINUTE);
        INSERT INTO `mydb`.`my_tbl`
            (`C1`,
            `C2`,
            `C3`)
            VALUES
            (p1, p2, exp);
        SET RINT = 1;
        RETURN RINT;
    END

ТАБЛИЦА - my_tbl

enter image description here

СЛУЧАЙ УСПЕХА - func1 ('AB C', '123456')

enter image description here

ИСКЛЮЧЕНИЕ: - func1 ('AB C ',' 123456789 ')

enter image description here

РЕДАКТИРОВАТЬ - Добавлены скриншоты

Ответы [ 3 ]

1 голос
/ 23 февраля 2020

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

Если вы объявили p2 varchar (20) и сохранили определение столбца varchar (6), вы, вероятно, могли бы получить желаемое поведение, потому что тогда исключение сработает внутри кода, охватываемого обработчиком исключений.

1 голос
/ 22 февраля 2020

Кажется, что mysql 8.0.19 не может перехватить все ошибки и обработать их должным образом.

Код ошибки: 1406. Данные слишком длинные для столбца 'p2' в строке 1

Код ошибки: 1049. Неизвестная база данных «mydb»

Это два примера, которые я тестировал и не работал, другие делают так, я думаю, это больше относится к mysql Форум.

DELIMITER $$
CREATE DEFINER=`mydb`@`localhost` FUNCTION `func1`(p1 varchar(50), p2 varchar(6)) RETURNS int
    READS SQL DATA
    DETERMINISTIC
BEGIN
    DECLARE EXP DATETIME;
    DECLARE RINT INT(1);
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
    BEGIn
       RETURN  0;
    END;
    SET exp = DATE_ADD(NOW(), INTERVAL 15 MINUTE);
    INSERT INTO `mydb`.`func1`
        (`C1`,
        `C2`,
        `C3`)
        VALUES
        (p1, p2, exp);
    SET RINT = 1;
    RETURN RINT;
END;
DE§LIMITER ;

Этот сценарий работает. Я увеличил для указанной переменной p2 размер, чтобы соответствовать введенным данным, и добавил обработчик выхода для ошибки 1265, которая является ошибкой, которую вы получаете при попытке вставить длинный текст.

Код ошибки: 1265. Данные, усеченные для столбца 'c2' в строке 1

DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `func1`(p1 varchar(50), p2 varchar(20)) RETURNS int
    MODIFIES SQL DATA
    DETERMINISTIC
BEGIN
    DECLARE EXP DATETIME;
    DECLARE RINT INT(1);
    BEGIN
    DECLARE EXIT HANDLER FOR 1265 RETURN 0;
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN 0;


    SET exp = DATE_ADD(NOW(), INTERVAL 15 MINUTE);
    INSERT INTO `mydb`.`my_tbl`
        (`C1`,
        `C2`,
        `C3`)
        VALUES
        (p1, p2, exp);
        SET RINT = 1;
        RETURN RINT;
    END;    
END$$
DELIMITER ;

Полученная ошибка выдает сообщение об ошибке еще до добавления HANDLER

0 голосов
/ 22 февраля 2020

Роль оператора TRY заключается в захвате исключения. (Поскольку этот процесс обычно состоит из нескольких операторов, вместо «оператора TRY» обычно используется термин «блок TRY».) Если в блоке TRY происходит исключение, то часть системы, называемая обработчиком исключения, доставляет исключение другому часть программы, которая обработает исключение. Эта программная часть обозначается ключевым словом CATCH и поэтому называется блоком CATCH.

NOTE

Обработка исключений с использованием операторов TRY и CATCH - это обычный способ, которым современные языки программирования, такие как C# и Java обработка ошибок.

Обработка исключений с помощью блоков TRY и CATCH дает программисту множество преимуществ, таких как:

Exceptions provide a clean way to check for errors without cluttering code
Exceptions provide a mechanism to signal errors directly rather than using some side effects
Exceptions can be seen by the programmer and checked during the compilation process

SQL Server 2012 вводит третий оператор в отношении обработки ошибок: THROW. Этот оператор позволяет генерировать исключение, пойманное в блоке обработки исключений. Проще говоря, оператор THROW - это еще один механизм возврата, который ведет себя подобно уже описанному оператору RAISEERROR.

В примере 1 показано, как работает обработка исключений с помощью TRY / CATCH / THROW. В нем показано, как можно использовать обработку исключений для вставки всех операторов в пакет или для отката всей группы операторов в случае возникновения ошибки. Пример основан на ссылочной целостности между таблицами отделов и сотрудников. По этой причине необходимо создать обе таблицы с использованием ограничений PRIMARY KEY и FOREIGN KEY.

ПРИМЕР 1

0270_001

После выполнения пакета в Примере 1, все три оператора в пакете не будут выполнены вообще, и результат этого примера:

0271_001

Выполнение примера 1 работает следующим образом. Первый оператор INSERT выполнен успешно. Затем второе утверждение вызывает ошибку ссылочной целостности. Поскольку все три оператора записаны внутри блока TRY, исключение «выбрасывается», и обработчик исключения запускает блок CATCH. CATCH откатывает все операторы и печатает соответствующее сообщение. После этого оператор THROW возвращает выполнение пакета вызывающей стороне. По этой причине содержимое таблицы сотрудника не изменится.

ПРИМЕЧАНИЕ

Операторы BEGIN TRANSACTION, COMMIT TRANSACTION и ROLLBACK являются операторами Transact- SQL относительно транзакций. Эти операторы запускают, фиксируют и откатывают транзакции соответственно. См. Главу 13 для обсуждения этих утверждений и транзакций в целом.

...