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

MySQL 存儲過程異常處理:DECLARE HANDLER 完整實戰指南

     編輯:MySQL 資料庫相關知識

語法結構

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

handler_type: CONTINUE | EXIT | UNDO (暫不支持)

condition_value:
  SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING      -- 01xxx 類警告
  | NOT FOUND       -- 02xxx 類、游標結束
  | SQLEXCEPTION    -- 除上述外所有錯誤
  | mysql_error_code

處理器類型行為對比

類型執行 statement 後適用場景
CONTINUE繼續執行後續語句記錄日志、設置標記、嘗試修復後繼續
EXIT退出當前 BEGIN...END 塊嚴重錯誤不可恢復、終止事務
UNDO回滾並退出(MySQL 暫不支持)—

條件值速記對照表

速記對應 SQLSTATE 類別典型場景
SQLWARNING01xxx數據截斷、非法值轉換、索引不存在等警告
NOT FOUND02xxxSELECT ... INTO 無結果、游標到達末尾
SQLEXCEPTION其他主鍵衝突、外鍵違反、語法錯誤、權限不足等

實戰示例 1:主鍵衝突 EXIT 處理

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);  -- 重複鍵錯誤,觸發 HANDLER,退出 BEGIN...END
  SET @x = 3;                -- 不會執行
END//
DELIMITER ;

CALL handler_demo_exit();
SELECT @x;  -- 結果: 2

實戰示例 2:主鍵衝突 CONTINUE 處理

DROP PROCEDURE IF EXISTS handler_demo_cont;
DELIMITER //
CREATE PROCEDURE handler_demo_cont()
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);  -- 錯誤但繼續
  SET @x = 3;                -- 執行
END//
DELIMITER ;

CALL handler_demo_cont();
SELECT @x;  -- 結果: 3

實戰示例 3:多條件處理器鏈

ALTER TABLE t ADD s2 INT NOT NULL;  -- 無默認值

DELIMITER //
CREATE PROCEDURE handler_multi()
BEGIN
  DECLARE CONTINUE HANDLER FOR 1062 BEGIN END;           -- 主鍵衝突
  DECLARE CONTINUE HANDLER FOR SQLWARNING                -- 警告 (如 1364 字段無默認值)
  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,觸發第 2 個 HANDLER 插入 (1,3)
  SET @x = 2;
  INSERT INTO t(s1) VALUES (1);  -- 錯誤 1062,觸發第 1 個 HANDLER 忽略
  SET @x = 3;
END//
DELIMITER ;

CALL handler_multi();
SELECT * FROM t;  -- 結果: (1,3)
SELECT @x;        -- 結果: 3

錯誤碼查找方法

  1. MySQL 安裝目錄 share/mysql/errmsg.txt
  2. 命令行工具:perror 1062 → Duplicate entry
  3. 官方文檔:Server Error Codes and Messages

最佳實踐建議

  1. 優先使用 SQLSTATE:標準化、跨版本穩定(如 '23000' 代表完整性約束違反)。
  2. 具體錯誤碼處理器置前:MySQL 按聲明順序匹配,先匹配具體碼(1062),再匹配類別(SQLEXCEPTION)。
  3. 處理器內避免複雜邏輯:僅做日志記錄、變量標記、簡單修復,防止遞歸觸發。
  4. 事務邊界清晰:EXIT HANDLER 會隱式回滾當前事務(若在事務中)。
  5. 游標 NOT FOUND 必須處理:否則游標循環會意外終止。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved