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

MySQL 變量與條件處理深度解析:DECLARE/SET/SELECT INTO、條件聲明、Handler 機制與事務回滾實戰

     編輯:MySQL 資料庫相關知識

變量定義與賦值三板斧

1. DECLARE 區域變量(僅限 BEGIN...END 塊開頭)


DECLARE var_name[,...] type [DEFAULT value];
-- 變量名不能帶 @,易與用戶變量/參數混淆
DECLARE pname VARCHAR(20) DEFAULT '陳';
DECLARE cnt INT DEFAULT 0;

2. SET 賦值(可同時聲明用戶變量)


-- 給已聲明變量賦值
SET pname = '王';

-- 邊聲明邊賦值(用戶變量,帶 @,作用域全會話)
SET @id = 1;

3. SELECT ... INTO 賦值(查詢結果直接入變量/參數)


-- 入區域變量
SELECT COUNT(*) INTO cnt FROM employee WHERE depid = pdepid;

-- 直接入 OUT 參數
SELECT COUNT(*) INTO pcount FROM employee WHERE depid = pdepid;

條件處理機制:讓存儲過程具備異常捕獲能力

步驟一:聲明條件名稱(可選,提高可讀性)


DECLARE reprimary CONDITION FOR 1062;           -- 錯誤碼
DECLARE dup_key CONDITION FOR SQLSTATE '23000'; -- SQLSTATE

步驟二:聲明 Handler(核心)


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

handler_type:
  CONTINUE  -- 執行 statement 後繼續後續邏輯
  EXIT      -- 執行 statement 後退出當前 BEGIN...END 塊
  UNDO      -- 保留未實現

condition_value:
  SQLSTATE 'xxxxx'
  condition_name
  SQLWARNING      -- 01 開頭 SQLSTATE 速記
  NOT FOUND       -- 02 開頭 SQLSTATE 速記(游標耗盡)
  SQLEXCEPTION    -- 其他所有錯誤
  mysql_error_code

實戰演示:主鍵衝突的三種處理姿勢

場景:批量插入,主鍵可能重複


CREATE TABLE Employee (
    id INT PRIMARY KEY, name VARCHAR(20), depid INT
);
INSERT INTO Employee VALUES (1,'陳',100);

姿勢 1:無 Handler → 直接報錯終止


CALL Pro_Insert_No_Handler();
-- ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
-- 後續語句不執行

姿勢 2:EXIT Handler → 記錄錯誤並退出


CREATE PROCEDURE Pro_Insert_Exit()
BEGIN
    DECLARE reprimary CONDITION FOR 1062;
    DECLARE EXIT HANDLER FOR reprimary SET @x = 1;
    
    SET @id = 1; INSERT INTO Employee VALUES (1,'陳',100);  -- 衝突
    SET @id = 2; INSERT INTO Employee VALUES (6,'陳',100);  -- 不執行
    SET @id = 3;
END;
CALL Pro_Insert_Exit();
SELECT @id, @x;  -- @id=1, @x=1

姿勢 3:CONTINUE Handler → 記錄錯誤並繼續


CREATE PROCEDURE Pro_Insert_Continue()
BEGIN
    DECLARE reprimary CONDITION FOR SQLSTATE '23000';
    DECLARE CONTINUE HANDLER FOR reprimary SET @x = 1;
    
    SET @id = 1; INSERT INTO Employee VALUES (1,'陳',100);  -- 衝突
    SET @id = 2; INSERT INTO Employee VALUES (6,'陳',100);  -- 執行
    SET @id = 3;
END;
CALL Pro_Insert_Continue();
SELECT @id, @x;  -- @id=3, @x=1

進階:結合事務實現「遇錯全盤回滾」


CREATE PROCEDURE Pro_Insert_Tx()
BEGIN
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @err = 1;
    
    START TRANSACTION;
    SET @id = 1; INSERT INTO Employee VALUES (7,'陳',100);  -- 成功
    SET @id = 2; INSERT INTO Employee VALUES (6,'陳',100);  -- 主鍵衝突
    SET @id = 3;
    
    IF @err = 1 THEN
        ROLLBACK;  -- id=7 也被回滾
    ELSE
        COMMIT;
    END IF;
END;

性能優化建議

  • 減少驗證頻率: 用事務包裹批量操作,僅在提交前檢查錯誤標誌
  • 優化 Handler 範圍: 盡量用具體錯誤碼/SQLSTATE 替代 SQLEXCEPTION
  • 游標循環中: 遇錯立即 LEAVE 循環,避免無效迭代

避坑指南

  1. DECLARE 必須在 BEGIN...END 開頭,且在所有語句之前
  2. 2. 區域變量無 @,用戶變量有 @,參數無 @ 但有 IN/OUT/INOUT 3. NOT FOUND 主要用於游標 FETCH 耗盡,非查詢無結果 4. UNDO HANDLER 尚未實現,勿使用 5. Handler 執行的 statement 只能是單條 SQL,塊語法需包在 BEGIN...END
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved