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

MySQL 動態 SQL 存儲過程:PREPARE + EXECUTE 實現運行時拼接查詢

     編輯:MySQL 資料庫相關知識

存儲過程中需根據傳入條件動態構建 WHERE 子句,使用 PREPARE/EXECUTE/DEALLOCATE PREPARE 三部曲。

標準模板

CREATE PROCEDURE sp_find(IN p_find VARCHAR(500))
BEGIN
    DECLARE v_sql VARCHAR(2000);
    SET @v_sql = CONCAT('SELECT * FROM your_table WHERE ', p_find);
    PREPARE stmt FROM @v_sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END

關鍵點

  1. 用戶變量 @v_sql:PREPARE 只接受用戶變量(@開頭),不接受局部變量(DECLARE)。
  2. CONCAT() 拼接:防止 SQL 注入需在應用層驗證 p_find 合法性,或改用參數化 PREPARE stmt FROM 'SELECT * FROM t WHERE col=?' + EXECUTE stmt USING @val。
  3. DEALLOCATE PREPARE:釋放語句句柄,避免會話級泄漏(最大 max_prepared_stmt_count,默認 16382)。

參數化版本(防注入)

CREATE PROCEDURE sp_find_param(IN p_col VARCHAR(64), IN p_val VARCHAR(255))
BEGIN
    SET @sql = CONCAT('SELECT * FROM your_table WHERE `', p_col, '` = ?');
    PREPARE stmt FROM @sql;
    SET @val = p_val;
    EXECUTE stmt USING @val;
    DEALLOCATE PREPARE stmt;
END

列名仍需拼接(識別符無法參數化),建議白名單校驗 p_col。

適用場景

  • 動態分表查詢(SELECT * FROM log_202401 WHERE ...)。
  • 可選過濾條件組合(前端傳 JSON,後端拼 SQL)。
  • DDL 自動化(ALTER TABLE ... ADD INDEX ...)。

限制

  • 預處理語句不支持某些 DDL(如 CREATE DATABASE)、SHOW、USE 等。
  • 會話級作用域,連接斷開自動釋放。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved