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;
? 佔位符,配合 EXECUTE ... USING @var 實現參數化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;
防止 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;