首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 預存程序異常處理完整指南:DECLARE HANDLER、CONTINUE/EXIT、SQLSTATE、錯誤碼與條件名稱

     編輯:MySQL 資料庫相關知識

語法結構

DECLARE handler_type HANDLER FOR condition_value[, ...] statement;

handler_type: CONTINUE | EXIT | UNDO(暫不支援)
condition_value:
  SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
| mysql_error_code

條件值速查

類別代表適用場景
SQLSTATE '23000'完整性約束違反(重複鍵、FK 失效)精確捕獲特定錯誤
1062Duplicate entry (MySQL 錯誤碼)等同 23000,更直觀
SQLWARNING所有 01 開頭的 SQLSTATE捕獲警告(如截斷、預設值)
NOT FOUND所有 02 開頭的 SQLSTATE + 游標結束游標迴圈結束控制
SQLEXCEPTION除上述外的所有錯誤兜底異常處理

實戰範例 1:EXIT HANDLER —— 遇重複鍵即退出

CREATE TABLE t (s1 INT PRIMARY KEY);

DELIMITER //
CREATE PROCEDURE handler_demo_exit()
BEGIN
  DECLARE EXIT HANDLER FOR SQLSTATE '23000' BEGIN END;  -- 靜默退出
  SET @x = 1; INSERT INTO t VALUES (1);
  SET @x = 2; INSERT INTO t VALUES (1);  -- 觸發 23000,程序結束
  SET @x = 3;
END//
DELIMITER ;

CALL handler_demo_exit(); SELECT @x;  -- 結果:2(第三句未執行)

實戰範例 2:CONTINUE HANDLER —— 遇錯誤繼續執行

TRUNCATE TABLE t;

DELIMITER //
CREATE PROCEDURE handler_demo_continue()
BEGIN
  DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' BEGIN END;
  SET @x = 1; INSERT INTO t VALUES (1);
  SET @x = 2; INSERT INTO t VALUES (1);  -- 觸發 23000,但繼續
  SET @x = 3;
END//
DELIMITER ;

CALL handler_demo_continue(); SELECT @x;  -- 結果:3(全執行完)

進階:多重 HANDLER 組合處理警告與錯誤

ALTER TABLE t ADD s2 INT NOT NULL;  -- 無預設值,INSERT 會產生警告 1364

DELIMITER //
CREATE PROCEDURE handler_combo()
BEGIN
  DECLARE CONTINUE HANDLER FOR 1062 BEGIN END;           -- 重複鍵忽略
  DECLARE CONTINUE HANDLER FOR SQLWARNING
  BEGIN UPDATE t SET s2 = 2; END;                        -- 警告時更新 s2=2
  DECLARE CONTINUE HANDLER FOR 1364
  BEGIN INSERT INTO t(s1,s2) VALUES (1,3); END;         -- 欄位無預設值錯誤時插入新行

  SET @x = 1; INSERT INTO t(s1) VALUES (1);  -- 警告 1364 → 觸發第三個 HANDLER
  SET @x = 2; INSERT INTO t(s1) VALUES (1);  -- 錯誤 1062 → 觸發第一個 HANDLER
  SET @x = 3;
END//
DELIMITER ;

CALL handler_combo();
SELECT * FROM t;  -- 僅有一行 (1,3)
SELECT @x;         -- 3

最佳實踐建議

  1. 優先使用 SQLSTATE:標準化、跨版本穩定,避免 MySQL 錯誤碼變更。
  2. EXIT 用於嚴重錯誤快速失敗,CONTINUE 用於可預期、可忽略的業務例外。
  3. 避免在 HANDLER 中執行複雜邏輯:難以除錯、影響效能,建議僅設標記變數、記錄日誌、插入審計表。
  4. 游標迴圈必備 NOT FOUND HANDLER:
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
  5. 測試覆蓋異常路徑:單元測試必須包含觸發 HANDLER 的輸入。

結語

MySQL 預存程序異常處理機制雖不如 Oracle/PLSQL 豐富,但 DECLARE HANDLER 搭配 SQLSTATE/ERROR CODE/SQLWARNING/NOT FOUND/SQLEXCEPTION 已能覆蓋 90% 業務異常場景。關鍵在於:**精確識別條件值、選擇正確 handler_type、保持 HANDLER 邏輯極簡**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved