依指定日期 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 | 釋放游標資源,必須執行。 |
UPDATE ... JOIN 或 INSERT ... ON DUPLICATE KEY UPDATE 完成集合運算,效能提升數量級。CALL getUserInfo('2008-03-08'); -- 指定日期
CALL getUserInfo(NULL); -- 用預設昨天