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

MySQL 動態游標實戰:Prepared Statement + View 實現運行時動態 SQL

     編輯:MySQL 資料庫相關知識

普通游標的 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 開頭的用戶

關鍵點

  1. PREPARE / EXECUTE / DEALLOCATE PREPARE 三部曲構建動態 SQL。
  2. View 僅為游標提供固定名稱的結果集入口,實際查詢由 Prepared Statement 決定。
  3. 存儲過程結束時 View 自動可見(Session 級),若併發調用建議用 TEMPORARY VIEW 或在 View 名加 Session ID 避免衝突。

進階:直接用 Prepared Statement 游標(MySQL 8.0+)

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 同樣

適用場景

  • 報表存儲過程:根據傳入維度動態選列/篩選條件。
  • 動態分表查詢:根據日期參數決定查哪張分表。
  • 多租戶隔離:根據 tenant_id 動態加 WHERE 條件。

動態游標讓存儲過程擁有類似應用層 ORM 的靈活查詢構建能力。

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