存儲過程中需根據傳入條件動態構建 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
PREPARE 只接受用戶變量(@開頭),不接受局部變量(DECLARE)。CONCAT() 拼接:防止 SQL 注入需在應用層驗證 p_find 合法性,或改用參數化 PREPARE stmt FROM 'SELECT * FROM t WHERE col=?' + EXECUTE stmt USING @val。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 ...)。ALTER TABLE ... ADD INDEX ...)。CREATE DATABASE)、SHOW、USE 等。