首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 存儲過程游標實戰:逐行處理查詢結果更新匯總表

     編輯:MySQL 綜合教學

案例需求

依指定日期 date_day,從 userInfo 讀取當日建立的用戶成績(語文、數學),逐行累加更新至 infoSum 表的 total 欄位。

完整存儲過程代碼

DELIMITER $$

DROP PROCEDURE IF EXISTS getUserInfo $$

CREATE PROCEDURE getUserInfo(IN date_day DATETIME)
BEGIN
    -- 變數宣告
    DECLARE _userName VARCHAR(12);
    DECLARE _chinese INT;
    DECLARE _math INT;
    DECLARE done INT DEFAULT 0;

    -- 定義游標:查詢指定日期的用戶成績
    DECLARE rs_cursor CURSOR FOR
        SELECT username, chinese, math
        FROM userInfo
        WHERE DATEDIFF(createDate, date_day) = 0;

    -- 定義 NOT FOUND 處理器:游標讀完設 done=1
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    -- 若未傳日期,預設為昨天
    IF date_day IS NULL THEN
        SET date_day = DATE_ADD(NOW(), INTERVAL -1 DAY);
    END IF;

    -- 開啟游標
    OPEN rs_cursor;

    cursor_loop: LOOP
        FETCH rs_cursor INTO _userName, _chinese, _math;

        IF done = 1 THEN
            LEAVE cursor_loop;
        END IF;

        -- 更新匯總表
        UPDATE infoSum
        SET total = _chinese + _math
        WHERE UserName = _userName;
    END LOOP cursor_loop;

    CLOSE rs_cursor;
END$$

DELIMITER ;

關鍵語法解析

語法說明
DECLARE ... CURSOR FOR SELECT ...定義游標綁定的查詢,不立即執行。
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1當 FETCH 讀無資料時觸發,設旗標讓迴圈結束。
OPEN cursor_name真正執行查詢、建立結果集指標。
FETCH cursor INTO var1, var2...取得下一列資料存入變數。
CLOSE cursor釋放游標資源,必須執行。

效能與替代方案

  • 游標屬逐列處理(RBAR),大量資料效能較差。
  • 本案例可改為單一 UPDATE ... JOIN 或 INSERT ... ON DUPLICATE KEY UPDATE 完成集合運算,效能提升數量級。
  • 游標適用於:需呼叫外部程式、複雜流程控制、動態 SQL 等無法集合化的情境。

呼叫方式

CALL getUserInfo('2008-03-08');  -- 指定日期
CALL getUserInfo(NULL);          -- 用預設昨天
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved