结论:不能将参数直接拼入单引号写成 like '%@keyword%',否则 sql server 视其为字面量而非变量;正确写法是用 concat('%', @search, '%') 或 '%' + @search + '%',并处理 null 和转义问题。

直接说结论:不能把参数直接拼进单引号里写成 LIKE '%@keyword%',否则查不到任何结果——SQL Server 把它当字面量处理,不是变量。
SQL Server 存储过程中 LIKE 拼接参数的正确写法
错误写法:WHERE name LIKE '%@search%' —— 这里 @search 不会被解析为变量值,而是当成字符串 "@search" 字面匹配。
正确做法是用 CONCAT 或 + 拼接通配符和参数:
-
WHERE name LIKE CONCAT('%', @search, '%')(SQL Server 2012+ 支持) -
WHERE name LIKE '%' + @search + '%'(兼容性更好,但注意@search为NULL时整表达式变NULL) - 若要防
NULL导致无结果,加判断:AND @search IS NOT NULL
MySQL 存储过程里 LIKE 的常见坑
MySQL 不支持 CONCAT 在 LIKE 右侧直接参与索引优化(即使字段有索引,LIKE '%xxx%' 仍会全表扫描)。
实操建议:
- 优先用
WHERE name LIKE CONCAT(@search, '%')(前缀匹配),可走索引 - 必须中/后模糊时,考虑用
LOCATE(@search, name) > 0,它在有索引字段上有时比LIKE '%xxx%'稍快(但仍是全扫) - 避免在参数前后都加
%后还指望走索引——这本质上就是放弃索引
多个字段同时模糊匹配的写法差异
比如要在 name、address、remark 三个字段中任一匹配关键词:
- SQL Server:
WHERE name LIKE '%' + @kw + '%' OR address LIKE '%' + @kw + '%' OR remark LIKE '%' + @kw + '%' - MySQL:
WHERE CONCAT(name, address, remark) LIKE CONCAT('%', @kw, '%')(不推荐:语义错乱,且无法利用各字段索引) - 更稳妥的 MySQL 写法:
WHERE name LIKE CONCAT('%', @kw, '%') OR address LIKE CONCAT('%', @kw, '%') OR remark LIKE CONCAT('%', @kw, '%') - 注意:多个
OR条件可能让执行计划退化,大数据量时建议拆成UNION ALL或改用全文索引
容易被忽略的转义与特殊字符问题
如果用户输入含 %、_ 或 [,默认会被当通配符解释,导致查出意外结果或 SQL 报错。
解决方案(以 SQL Server 为例):
- 先定义转义字符,比如
ESCAPE '' - 预处理参数:
SET @search = REPLACE(REPLACE(@search, '', '\'), '%', '%') - 查询时写:
WHERE name LIKE '%' + @search + '%' ESCAPE '' - MySQL 类似,但需用
ESCAPE配合LIKE,且REPLACE函数行为一致
真正难的不是写出来,而是想到用户会输什么、数据库怎么解析、索引是否失效、转义有没有漏——这些地方一漏,线上就查慢或查错。











