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
在此先感謝。
感謝您的回答。我在閱讀你的答案後意識到,我只是增加了新內容,並且在更新之後沒有其他語句,所以我意識到不需要像你所說的那樣編寫一個繼續處理程序。當你說「..不允許程序控制交易」時,你能解釋一下嗎?將事務放入存儲過程中不可取?另外,我一直在閱讀這個https://dev.mysql.com/doc/refman/5.5/en/error-types.html,但是當我輸入「CALL mysql_errno()」時,它在工作臺上返回一個錯誤,它不存在。任何方式來打印錯誤? TNX。 – p3ace
'mysql_errno()'不是存儲過程。它是C客戶端庫中的一個C函數(在文檔中使用「call」一詞意味着調用該函數,而不是'CALL'一個存儲過程)。它用於獲取實際拋出給客戶端的錯誤 - 不是一個被處理程序捕獲的錯誤,所以對你沒有幫助。如上所示使用'RESIGNAL'可以讓您在清理後重新拋出剛剛捕獲的錯誤。 –
由於上述原因,在程序中放置事務控制並不是一個好主意:如果您在事務中已經調用了這樣一個過程,那麼當前事務就會默默承諾,並且當過程完成時,您不在交易,但你沒有意識到這一事實。希望你能看到這會如何導致意想不到的行爲 - 遠距離的恐怖行爲,就像它一樣。 –