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

MySQL 存儲過程游標實戰:聲明、循環遍歷與更新聚合結果

     編輯:MySQL 資料庫相關知識

完整代碼

CREATE PROCEDURE `justifyGroupNum`()
NOT DETERMINISTIC
SQL SECURITY DEFINER
COMMENT ''
BEGIN
    /* 調用方式:CALL justifyGroupNum() */
    DECLARE p_group_id INT;
    DECLARE p_num INT;
    DECLARE stopFlag INT DEFAULT 0;

    DECLARE cursor_name CURSOR FOR
        SELECT c_group_id, COUNT(*) AS num
        FROM `t_group_member`
        WHERE c_valid IN (3,4)
        GROUP BY c_group_id;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET stopFlag = 1;

    OPEN cursor_name;
    REPEAT
        FETCH cursor_name INTO p_group_id, p_num;
        BEGIN
            UPDATE t_groupinfo 
            SET c_member_number = p_num 
            WHERE c_group_id = p_group_id;
        END;
    UNTIL stopFlag = 1
    END REPEAT;
    CLOSE cursor_name;
END;

核心要點

  1. 游標聲明:DECLARE cursor_name CURSOR FOR SELECT ... 定義結果集。
  2. NOT FOUND 處理器:DECLARE CONTINUE HANDLER FOR NOT FOUND SET stopFlag = 1; —— 必須,否則 FETCH 結束時拋出異常導致過程終止。
  3. REPEAT ... UNTIL 循環:至少執行一次,配合 stopFlag 退出。WHILE 同理需先 FETCH 再判斷。
  4. OPEN / FETCH / CLOSE:標準游標生命周期,用完必須 CLOSE 釋放資源。
  5. 調用方式:CALL justifyGroupNum();

常見坑與最佳實踐

  • 忘記 NOT FOUND HANDLER → 游標讀完報錯「No data to FETCH」。
  • 未 CLOSE 游標 → 連接洩漏,佔用服務端資源。
  • 游標內執行 DML 可能觸發鎖等待,大數據量建議分批提交或改用單條 SQL(如 UPDATE ... JOIN (SELECT ...))。
  • MySQL 8.0+ 推薦用 CTE + 窗口函數或單條多表 UPDATE 替代游標,性能更優。

現代化替代方案(MySQL 8.0+)

UPDATE t_groupinfo g
JOIN (
    SELECT c_group_id, COUNT(*) AS num
    FROM t_group_member
    WHERE c_valid IN (3,4)
    GROUP BY c_group_id
) m ON g.c_group_id = m.c_group_id
SET g.c_member_number = m.num;

單條 SQL 替代游標循環,原子性更強、性能更高、代碼更簡潔。

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