You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带IN参数的MySQL动态查询存储过程参数替换异常问题

解决MySQL存储过程动态SQL参数替换问题

问题现状

你编写的存储过程SP_TEST_1在生成动态查询时,未能将p_search参数的实际值(如peter)代入SQL语句,而是直接输出了字符串%@p_search%,导致查询无法匹配目标数据。

解决方案

方法1:直接拼接参数值到动态SQL(适用于需要生成带实际值的SQL语句场景)

修改存储过程中拼接LIKE条件的代码,将p_search参数与通配符%直接拼接,同时正确转义单引号:

USE test;

DELIMITER $$
CREATE PROCEDURE `SP_TEST_1`(
    IN `p_criteria` VARCHAR(50),
    IN `p_search` VARCHAR(50)
)
BEGIN
    DECLARE v_Query VARCHAR(4000); 
    SET v_Query = '';
    -- 原代码中CONCAT的两个单引号是转义写法,若需拼接空格可改为' '
    SET v_Query = 'SELECT CONCAT(u.firstname, '''', u.lastname) as group_name FROM users u';
    
    IF (p_criteria IS NOT NULL AND p_criteria = 'name') THEN
        SET v_Query = CONCAT(v_Query, ' WHERE LOWER(u.firstname)');
        -- 修正参数拼接逻辑:将p_search与通配符拼接,转义单引号
        SET v_Query = CONCAT(v_Query, ' LIKE LOWER(''%', p_search, '%'')');
    END IF;
    
    INSERT INTO testsql(qry) VALUES(CONCAT('q=', v_Query));             
    
    COMMIT;
    SET @result_set = v_Query;
    PREPARE statement FROM @result_set;
    EXECUTE statement;
    DEALLOCATE PREPARE statement;
END$$
DELIMITER ;

方法2:使用预编译参数传递(更安全,避免SQL注入)

如果不需要在生成的SQL语句中直接显示实际参数值,推荐使用预编译占位符,通过USING子句传递参数,这是生产环境更安全的做法:

USE test;

DELIMITER $$
CREATE PROCEDURE `SP_TEST_1`(
    IN `p_criteria` VARCHAR(50),
    IN `p_search` VARCHAR(50)
)
BEGIN
    DECLARE v_Query VARCHAR(4000); 
    SET v_Query = '';
    SET v_Query = 'SELECT CONCAT(u.firstname, '''', u.lastname) as group_name FROM users u';
    
    IF (p_criteria IS NOT NULL AND p_criteria = 'name') THEN
        SET v_Query = CONCAT(v_Query, ' WHERE LOWER(u.firstname) LIKE LOWER(CONCAT(''%'', ?, ''%''))');
    END IF;
    
    INSERT INTO testsql(qry) VALUES(CONCAT('q=', v_Query));             
    
    COMMIT;
    SET @result_set = v_Query;
    PREPARE statement FROM @result_set;
    -- 通过USING传递参数
    IF (p_criteria IS NOT NULL AND p_criteria = 'name') THEN
        EXECUTE statement USING p_search;
    ELSE
        EXECUTE statement;
    END IF;
    DEALLOCATE PREPARE statement;
END$$
DELIMITER ;

说明

  • 方法1会直接将参数值拼接到生成的SQL语句中,满足你需要看到实际值的需求,但要注意参数中含特殊字符(如单引号)可能导致SQL语法错误,需额外处理。
  • 方法2使用预编译占位符,避免了SQL注入风险,同时参数传递更安全,适合大多数生产场景。

内容的提问来源于stack exchange,提问作者habubacker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 18:25:27