標準語法
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' / 1062:重複鍵衝突
- SQLWARNING:所有 01 開頭警告
- NOT FOUND:02 開頭 / 游標越界
- SQLEXCEPTION:除上述外的所有錯誤
- 完整錯誤碼表:
mysql_install_dir/share/mysql/errmsg.txt 或 官方文檔
實戰範例 1:EXIT HANDLER 遇重複鍵退出
CREATE TABLE t (s1 INT PRIMARY KEY);
DELIMITER //
CREATE PROCEDURE handlerdemo()
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 handlerdemo(); SELECT @x; -- 結果 @x=2,第三條未執行
實戰範例 2:CONTINUE HANDLER 遇錯繼續
TRUNCATE TABLE t;
DROP PROCEDURE IF EXISTS handlerdemo;
DELIMITER //
CREATE PROCEDURE handlerdemo()
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 handlerdemo(); SELECT @x; -- 結果 @x=3,全程執行完畢
實戰範例 3:多層 HANDLER 處理警告與錯誤
ALTER TABLE t ADD s2 INT NOT NULL; -- 無默認值,插入會警告 1364
DELIMITER //
CREATE PROCEDURE handlerdemo()
BEGIN
DECLARE CONTINUE HANDLER FOR 1062 BEGIN END; -- 忽略重複鍵
DECLARE CONTINUE HANDLER FOR SQLWARNING -- 捕獲警告
BEGIN UPDATE t SET s2 = 2; END;
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
SET @x = 2;
INSERT INTO t(s1) VALUES (1); -- 觸發 1062
SET @x = 3;
END//
DELIMITER ;
CALL handlerdemo();
SELECT * FROM t; -- 僅剩 (1,3),警告處理器未生效因 1364 優先匹配
關鍵原則
- HANDLER 優先級:具體錯誤碼 > SQLSTATE > 速記條件 (SQLWARNING/SQLEXCEPTION/NOT FOUND)
CONTINUE 適合「記錄日誌、修正數據後繼續」;EXIT 適合「不可恢復、快速失敗」
- MySQL 8.0 引入
GET DIAGNOSTICS 可在 HANDLER 內獲取詳細錯誤資訊