踩坑經歷(五)一次關於MySQL儲存過程的排錯
阿新 • • 發佈:2018-11-16
SQL語句
-- #開啟定時器,預設為關閉狀態 set global event_scheduler =1; #或者set GLOBAL event_scheduler = ON; use monitorsys; drop event if exists report_back_exception_2_task; delimiter $$ create event report_back_exception_2_task -- 每週五晚上23點執行 ON SCHEDULE EVERY 1 WEEK STARTS DATE_ADD(DATE_ADD('2018-11-09', INTERVAL 1 DAY), INTERVAL -772 MINUTE) -- show events -- SELECT DATE_ADD(DATE_ADD('2018-11-08', INTERVAL 1 DAY), INTERVAL -773 MINUTE) -- SELECT * FROM task_log 6分鐘延遲 do begin DECLARE t_error INTEGER DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1; # 異常時為1 #開始資料統計處理事務 start transaction; set current_date_=NOW(); IF t_error=1 THEN INSERT INTO task_log(logType,procName,time,msg) VALUES('event','report_back_exception_2_task',NOW(),'資管/基金:偏離比較基準50bp-100bp的交易統計錯誤。'); ROLLBACK; ELSE INSERT INTO task_log(logType,procName,time,msg) VALUES('event','report_back_exception_2_task',NOW(),'資管/基金:偏離比較基準50bp-100bp的交易統計執行成功!'); COMMIT; END IF; end $$ delimiter ;
我認為的執行結果:task_log表中新增一條資料
INSERT INTO task_log(logType,procName,time,msg)
VALUES('event','report_back_exception_2_task',NOW(),'資管/基金:偏離比較基準50bp-100bp的交易統計執行成功!');
實際執行結果:沒有插入任何資料
排查過程
(1) 註釋掉開始事物的SQL
-- start transaction;
執行結果:沒有插入任何資料
(2)註釋掉時間的SQL
-- set current_date_=NOW();
執行結果: 正常插入資料
INSERT INTO task_log(logType,procName,time,msg)
VALUES('event','report_back_exception_2_task',NOW(),'資管/基金:偏離比較基準50bp-100bp的交易統計執行成功!');
疑問
為啥日期賦值語句SQL報錯不被捕獲,沒有進入if語句,直接停止往下執行
解答
(1)日期型別長度為varchar(12),now()的長度為19,所以日期資料賦值失敗
(2)MySQL在預設情況 下(也就是我們沒有定義處理錯誤的方法-handler)自己的錯誤處理機制,對於SQLWARNING和NOT FOUND的處理方法就是無視錯誤繼續執行。對於SQLEXCEPTION的話,其預設的處理方法是在出現錯誤的地方就終止掉了。
(3)使用START TRANSACTION,自動提交將保持禁用狀態,直到你使用COMMIT或ROLLBACK結束事務。一句話來說就是,手動開啟事物要手動關閉。
IF t_error=1 THEN
ROLLBACK;
INSERT INTO task_log(logType,procName,time,msg)
VALUES('event','report_back_exception_2_task',NOW(),'sqlexception異常。');
(4)使用START TRANSACTION開啟事物,不提交也不回滾,會直接導致死鎖
提示:注意會話隔離