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

MySQL 儲存程序錯誤處理機制完整指南:DECLARE HANDLER、條件優先級與作用域

     編輯:MySQL 資料庫相關知識

HANDLER 語法全貌

DECLARE {CONTINUE | EXIT} HANDLER
  FOR {SQLSTATE sqlstate_code | MySQL_error_code | condition_name}
  handler_statement;

三大核心要素

  1. 處理類型:
    • CONTINUE:執行 handler_statement 後**繼續**當前 BEGIN...END 區塊
    • EXIT:執行 handler_statement 後**退出**當前 BEGIN...END 區塊
  2. 觸發條件(三選一):
    • MySQL 錯誤碼(如 1062 Duplicate Key)
    • ANSI SQLSTATE(如 '23000' Integrity Constraint Violation)
    • 命名條件:SQLEXCEPTION (所有錯誤)、SQLWARNING (警告)、NOT FOUND (游標無數據)
  3. 處理動作:單條 SQL 語句(可用 BEGIN ... END 包裹多條)

實戰範例

範例 1:捕獲重複鍵錯誤,標記繼續

DECLARE CONTINUE HANDLER FOR 1062 SET @duplicate_key = 1;
-- 等價於
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @duplicate_key = 1;

範例 2:捕獲所有 SQL 異常

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @l_error = 1;

範例 3:自定義命名條件

DECLARE foreign_key_error CONDITION FOR 1216;  -- 或 SQLSTATE '23000'
DECLARE CONTINUE HANDLER FOR foreign_key_error
BEGIN
  INSERT INTO error_log (msg) VALUES ('Foreign key violation');
  SET @fk_error = 1;
END;

捕獲優先級鐵律(同一錯誤只能被一個 HANDLER 捕獲)

MySQL 錯誤碼 > SQLSTATE > 命名條件 (SQLEXCEPTION/SQLWARNING/NOT FOUND)

定義順序不影響優先級,具體碼永遠優先於通用類別。

作用域規則

  1. 生效範圍:僅包含 HANDLER 定義的 BEGIN ... END 區塊內的語句
  2. 巢狀區塊隔離:內層 BEGIN ... END 定義的 HANDLER **不保護** 外層同級語句

作用域示範

-- 1. 區塊級生效
DECLARE CONTINUE HANDLER FOR 1048 SELECT 'Null insert attempted';
BEGIN
  INSERT INTO a VALUES (6, NULL);  -- 觸發 1048,被捕獲
END;

-- 2. 內層定義不保護外層
BEGIN
  BEGIN
    DECLARE CONTINUE HANDLER FOR 1216 SELECT 'FK violated';
  END;
  INSERT INTO departments ...;  -- 此處 1216 **不會** 被捕獲!
END;

常見錯誤碼速查表(節錄高頻)

MySQL 錯誤碼SQLSTATE含義
102223000Duplicate key
104823000Column cannot be null
106223000Duplicate entry
1114HY000Table is full
1205HY000Lock wait timeout
121623000Foreign key constraint fails (child)
121723000Foreign key constraint fails (parent)
124221000Subquery returns > 1 row
131770100Query execution interrupted
132902000No data to FETCH

最佳實踐建議

  1. **最外層 BEGIN...END 定義通用 HANDLER**(SQLEXCEPTION/SQLWARNING/NOT FOUND)作為最後防線
  2. **具體業務邏輯區塊定義具體 HANDLER**(錯誤碼/SQLSTATE)精準處理
  3. 避免在 HANDLER 內執行複雜邏輯,僅做標記、記錄、簡單補償
  4. 測試時故意觸發錯誤,驗證 HANDLER 行為與變數狀態
  5. 記住:EXIT 只退出當前區塊,外層邏輯繼續執行
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved