2016-07-22 30 views
2

返回mysql存儲過程中事務中錯誤原因的最佳方式是什麼?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

使用CONTINUE HANDLER在這裏完全不合適。在發生錯誤後,您允許其餘查詢運行,這最多浪費時間和資源,因爲您正在執行已知的將會回滾的查詢。相反,像這樣的東西似乎是一個更好的計劃:

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

但是,最佳做法是不允許過程控制事務。如果調用會話已經保存了一個事務,程序中的START TRANSACTION;將默默地隱含地提交它,使得調用者處於無法回滾的狀態並且不知道該狀況。

+1

感謝您的回答。我在閱讀你的答案後意識到,我只是增加了新內容,並且在更新之後沒有其他語句,所以我意識到不需要像你所說的那樣編寫一個繼續處理程序。當你說「..不允許程序控制交易」時,你能解釋一下嗎?將事務放入存儲過程中不可取?另外,我一直在閱讀這個https://dev.mysql.com/doc/refman/5.5/en/error-types.html,但是當我輸入「CALL mysql_errno()」時,它在工作臺上返回一個錯誤,它不存在。任何方式來打印錯誤? TNX。 – p3ace

+0

'mysql_errno()'不是存儲過程。它是C客戶端庫中的一個C函數(在文檔中使用「call」一詞意味着調用該函數,而不是'CALL'一個存儲過程)。它用於獲取實際拋出給客戶端的錯誤 - 不是一個被處理程序捕獲的錯誤,所以對你沒有幫助。如上所示使用'RESIGNAL'可以讓您在清理後重新拋出剛剛捕獲的錯誤。 –

+0

由於上述原因,在程序中放置事務控制並不是一個好主意:如果您在事務中已經調用了這樣一個過程,那麼當前事務就會默默承諾,並且當過程完成時,您不在交易,但你沒有意識到這一事實。希望你能看到這會如何導致意想不到的行爲 - 遠距離的恐怖行爲,就像它一樣。 –