MySQL捕获事务中的异常

时间:2016-07-22 05:02:21

标签: mysql sql exception-handling transactions

在mysql存储过程中返回事务中错误原因的最佳方法是什么?

这是我创建的一个存储过程。但是我注意到如果我在语法上提交错误,比如说我忘了将WHERE子句放在update语句之一中,它只会返回SELECT 'error'但不会发生错误的实际原因。

有没有更好的方法来捕获错误,就像你刚刚放入

的Java一样
catch(SQLException e){
JOptionPane.showMessageDialog(null,e.getError()+"\n"+e.getMessage() );
}

我很欣赏任何示例或最佳实践。

CREATE DEFINER=`root`@`localhost` PROCEDURE `updateCurriculumDetails`(p_curriculumId INT, p_editedByUserId INT, p_curriculumName varchar(50), p_description VARCHAR(200), p_gradeLevelId INT, p_schoolYearId INT)
BEGIN

    DECLARE hasError BOOLEAN DEFAULT 0;
    DECLARE CONTINUE HANDLER FOR sqlexception SET hasError = 1;


    START TRANSACTION;

        UPDATE curriculum_dt c
            SET     c.`name`        = p_curriculumName, 
                    c.description   = p_description,
                    c.gradeLevelId  = p_gradeLevelId 
            WHERE   c.id            = p_curriculumId;

        UPDATE curriculum_schoolyears_dt cs
            SET     cs.schoolYearId = p_schoolYearId
            WHERE   cs.curriculumId = p_curriculumId;

        UPDATE curriculum_hd SET editedBy_UserId = p_editedByUserId,
        dateLastEdited = NOW()
            WHERE curriculumId = p_curriculumId;


    IF hasError THEN
        ROLLBACK;
        SELECT 'error';
    ELSE
        COMMIT;
        SELECT 'successfully updated' AS result;

    END IF;

END

提前致谢。

1 个答案:

答案 0 :(得分:1)

使用CONTINUE HANDLER在这里完全不合适。您在发生错误后允许其余查询运行,这最多是浪费时间和资源,因为您正在执行已知的查询将被回滚。相反,像这样的事情似乎是一个更好的计划:

DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
  ROLLBACK;
  RESIGNAL;
END;

但是,最佳做法是不允许程序控制交易。如果调用会话已经拥有一个事务,那么该过程中的START TRANSACTION;将以静默方式隐式提交它,使调用者处于无法回滚且不知道该条件的不利位置。