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

MySQL 動態游標實戰:Prepared Statement + View 實現動態查詢

     編輯:MySQL 綜合教學

MySQL 動態游標實戰:Prepared Statement + View 實現動態查詢

MySQL 原生游標只支援靜態 SQL,若需根據參數動態構建查詢(如動態表名、動態 WHERE 條件),可結合預處理語句與視圖繞過限制。本文示範完整實現流程。

核心原理

  1. 在存儲過程中根據輸入參數動態拼接 SQL 字串。
  2. 使用 PREPARE、EXECUTE 建立並執行動態視圖。
  3. 游標針對該視圖進行靜態查詢,實現參數化結果集遍歷。

完整範例:依用戶名稱前綴查詢

-- 建立測試表與資料
CREATE TABLE webuser (username VARCHAR(10));
INSERT INTO webuser VALUES ('a1'),('a2'),('a3'),('b1'),('b2'),('b3');

-- 建立存儲過程
DROP PROCEDURE IF EXISTS dynamic_cursor;
DELIMITER //
CREATE PROCEDURE dynamic_cursor (IN p_name VARCHAR(10))
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE v_username VARCHAR(10);
    
    -- 1. 宣告游標指向視圖(視圖稍後動態建立)
    DECLARE cur CURSOR FOR SELECT username FROM webuser_view;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    
    -- 2. 動態建立/重建視圖
    DROP VIEW IF EXISTS webuser_view;
    SET @sqlstr = CONCAT("CREATE VIEW webuser_view AS SELECT username FROM webuser WHERE username LIKE '", p_name, "%'");
    PREPARE stmt FROM @sqlstr;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    -- 3. 遍歷游標
    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO v_username;
        IF done THEN LEAVE read_loop; END IF;
        SELECT v_username AS `動態查詢結果`;
    END LOOP;
    CLOSE cur;
END//
DELIMITER ;

-- 測試呼叫
CALL dynamic_cursor('a');

關鍵點解析

  • 視圖名稱固定: 游標宣告時需指定確定的視圖名(webuser_view),故每次呼叫前必須 DROP VIEW IF EXISTS 再重建。
  • SQL 注入風險: 參數直接拼接字串存在風險,生產環境務必對 p_name 進行轉義或驗證(如 QUOTE())。
  • 效能考量: 頻繁建立/刪除視圖會產生元數據鎖,高併發場景建議改用應用層動態 SQL 或臨時表。
  • 作用域限制: 視圖為 Session 級別,多併發呼叫不會互相干擾。

替代方案比較

方案優點缺點
動態視圖 + 游標純 SQL 實現,邏輯封裝在 DBDDL 開銷大,不適合高頻呼叫
應用層拼接 SQL靈活、效能好、易除錯業務邏輯分散,需防注入
臨時表 + 游標避免 DDL 鎖,支援複雜中間結果需手動管理臨時表生命週期

適用場景: 報表類、批次處理、低頻呼叫的動態查詢封裝。高併發核心業務請優先考慮應用層方案。

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