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

MySQL 異常處理機制詳解:條件聲明、處理器類型與實戰案例

     編輯:MySQL 資料庫相關知識

異常處理架構

MySQL 存儲程序支援結構化異常處理:聲明條件 → 聲明處理器 → 捕獲執行,確保業務邏輯在錯誤發生時可控繼續或優雅退出。

1. 條件聲明 (DECLARE CONDITION)

語法

DECLARE condition_name CONDITION FOR condition_type;

condition_type:
    SQLSTATE [VALUE] sqlstate_value
  | mysql_error_code

示例

-- 方式一:SQLSTATE (標準 SQL 狀態碼)
DECLARE duplicate_key CONDITION FOR SQLSTATE '23000';

-- 方式二:MySQL 錯誤碼
DECLARE duplicate_key CONDITION FOR 1062;
SQLSTATE '23000' 對應完整性約束違反 (主鍵衝突、唯一鍵衝突、外鍵約束等),1062 為 MySQL 具體錯誤碼「Duplicate entry」。

2. 處理器聲明 (DECLARE HANDLER)

語法

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

handler_type:
    CONTINUE  -- 執行 statement 後繼續後續語句
  | EXIT      -- 執行 statement 後退出當前 BEGIN...END 塊
  | UNDO      -- 回滾 (MySQL 暫不支援)

condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING      -- 所有 01 開頭 SQLSTATE
  | NOT FOUND       -- 所有 02 開頭 SQLSTATE (游標無數據等)
  | SQLEXCEPTION    -- 所有未被上述捕獲的錯誤
  | mysql_error_code

六種捕獲模式實戰

-- 1. 捕獲具體 SQLSTATE
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @msg = 'Duplicate key';

-- 2. 捕獲具體錯誤碼
DECLARE CONTINUE HANDLER FOR 1062 SET @msg = 'Duplicate entry';

-- 3. 先聲明條件再捕獲 (推薦,可讀性強)
DECLARE duplicate_key CONDITION FOR 1062;
DECLARE CONTINUE HANDLER FOR duplicate_key SET @msg = 'Duplicate entry';

-- 4. 捕獲所有警告
DECLARE EXIT HANDLER FOR SQLWARNING SET @msg = 'Warning occurred';

-- 5. 捕獲 NOT FOUND (游標結束/SELECT 無結果)
DECLARE EXIT HANDLER FOR NOT FOUND SET @msg = 'No data found';

-- 6. 捕獲所有異常 (兜底)
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @msg = 'Error occurred';

3. 綜合實戰案例

場景:向帶主鍵的表插入測試數據,觀察異常處理行為

CREATE TABLE location (
    location_id INT PRIMARY KEY,
    location_name VARCHAR(50)
);

案例 1:無異常處理 (默認 EXIT)

DELIMITER //
CREATE PROCEDURE insert_no_handler()
BEGIN
    SET @x = 1;
    INSERT INTO location VALUES (1, 'Beijing');
    SET @x = 2;
    INSERT INTO location VALUES (1, 'Wuxi');  -- 主鍵衝突
    SET @x = 3;
END //
DELIMITER ;

CALL insert_no_handler();
SELECT @x;  -- 結果: 2 (第二條 INSERT 失敗,默認 EXIT 退出)

案例 2:CONTINUE 處理器

DELIMITER //
CREATE PROCEDURE insert_with_continue()
BEGIN
    DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @err = 1;
    
    SET @x = 1;
    INSERT INTO location VALUES (1, 'Beijing');
    SET @x = 2;
    INSERT INTO location VALUES (1, 'Wuxi');  -- 觸發處理器
    SET @x = 3;
END //
DELIMITER ;

CALL insert_with_continue();
SELECT @x;  -- 結果: 3 (繼續執行到結尾)
SELECT @err; -- 結果: 1

4. 關鍵結論與最佳實踐

變量作用域

  • @var 用戶會話變量,連接級別,客戶端斷開自動釋放
  • DECLARE var 局部變量,僅在 BEGIN...END 塊內有效
  • 測試時建議重新連接清理會話變量干擾

處理器選型指南

業務需求推薦類型說明
記錄錯誤日誌,繼續處理後續記錄CONTINUE批量導入、數據清洗
關鍵業務失敗即停止,上層事務回滾EXIT轉賬、扣款等強一致性場景
游標遍歷結束標誌NOT FOUNDFETCH 循環結束條件

優先級規則

  1. 具體錯誤碼/條件名稱優先級最高
  2. SQLWARNING / NOT FOUND / SQLEXCEPTION 為通用捕獲,優先級遞減
  3. 同一塊中可聲明多個處理器,按優先級匹配

總結

MySQL 異常處理雖不如 Java/Go 豐富,但掌握 CONDITION + HANDLER (CONTINUE/EXIT) + SQLEXCEPTION/SQLWARNING/NOT FOUND 核心組合,足以應對存儲過程中 95% 的錯誤控制場景。核心原則:具體錯誤具體捕獲,通用異常兜底記錄,關鍵業務用 EXIT 保護事務邊界。

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