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

MySQL 存儲過程中執行動態 SQL 的標準模式

     編輯:MySQL 資料庫相關知識

核心三步驟

PREPARE stmt_name FROM @sql_variable;
EXECUTE stmt_name;
DEALLOCATE PREPARE stmt_name;

完整示例

DROP PROCEDURE IF EXISTS my_procedure;
CREATE PROCEDURE my_procedure()
BEGIN
    DECLARE my_sql VARCHAR(500);
    
    -- 構建動態 SQL(可包含變量拼接)
    SET my_sql = 'SELECT * FROM aa_list';
    
    -- 必須賦值給用戶變量(@開頭),PREPARE 不支持局部變量
    SET @ms = my_sql;
    
    -- 準備、執行、釋放
    PREPARE s1 FROM @ms;
    EXECUTE s1;
    DEALLOCATE PREPARE s1;
END;

關鍵規則

  1. PREPARE 只接受用戶變量(@var),不支持局部變量(DECLARE 定義)
  2. 動態 SQL 可包含 ? 佔位符,配合 EXECUTE ... USING @var 實現參數化
  3. DEALLOCATE PREPARE 必須調用,否則會話結束前佔用 prepared statement 額度

帶參數動態查詢示例

CREATE PROCEDURE dynamic_query(IN table_name VARCHAR(64), IN min_id INT)
BEGIN
    SET @sql = CONCAT('SELECT * FROM `', table_name, '` WHERE id > ?');
    PREPARE stmt FROM @sql;
    SET @min_id = min_id;
    EXECUTE stmt USING @min_id;
    DEALLOCATE PREPARE stmt;
END;

應用場景

  • 表名/列名動態(無法用普通參數化)
  • 複雜條件動態構建(可選 WHERE 子句)
  • 分表查詢路由
  • DDL 語句動態執行(如動態建分區)

安全警示

防止 SQL 注入:拼接表名/列名時必須用 QUOTE() 或手動驗證白名單,絕不可直接拼接用戶輸入。

-- 安全做法
SET @table = 'user_logs';
IF @table IN ('user_logs', 'order_logs', 'system_logs') THEN
    SET @sql = CONCAT('SELECT * FROM `', @table, '`');
    PREPARE stmt FROM @sql;
    ...
END IF;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved