普通游標的 SELECT 在定義時就固定。若需根據傳入參數動態構建查詢(如 WHERE username LIKE 'prefix%'),可用 Prepared Statement 建立 View → 對 View 開游標 技巧。
DELIMITER //
DROP PROCEDURE IF EXISTS dynamic_cursor //
CREATE PROCEDURE dynamic_cursor(IN p_name VARCHAR(10))
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE v_username VARCHAR(10);
-- 1. 動態建立 View
DROP VIEW IF EXISTS webuser_view;
SET @sql = CONCAT("CREATE VIEW webuser_view AS SELECT username FROM webuser WHERE username LIKE '", p_name, "%'");
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 2. 針對 View 宣告游標
DECLARE cur CURSOR FOR SELECT username FROM webuser_view;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_username;
IF done THEN LEAVE read_loop; END IF;
SELECT v_username; -- 業務處理
END LOOP;
CLOSE cur;
END //
DELIMITER ;
-- 測試
CALL dynamic_cursor('a'); -- 查詢以 a 開頭的用戶
PREPARE / EXECUTE / DEALLOCATE PREPARE 三部曲構建動態 SQL。TEMPORARY VIEW 或在 View 名加 Session ID 避免衝突。MySQL 8.0 支援 DECLARE cur CURSOR FOR stmt_name; 直接綁定 Prepared Statement,無需 View 中轉:
SET @sql = 'SELECT username FROM webuser WHERE username LIKE ?';
PREPARE stmt FROM @sql;
SET @param = CONCAT(p_name, '%');
DECLARE cur CURSOR FOR EXECUTE stmt USING @param;
-- 後續 FETCH 同樣
動態游標讓存儲過程擁有類似應用層 ORM 的靈活查詢構建能力。