在SQL Server中转义字符串,以便可以在LIKE表达式中安全使用


78

如何在SQL Server的存储过程中转义字符串,以便可以在LIKE表达式中安全使用。

假设我有一个NVARCHAR像这样的变量:

declare @myString NVARCHAR(100);

我想在LIKE表达式中使用它:

... WHERE ... LIKE '%' + @myString + '%';

如何转义字符串(更具体地说,是对LIKE模式匹配有意义的字符,例如%?在T-SQL中或),以便可以安全地以这种方式使用?

例如,给定:

@myString = 'aa%bb'

我想要:

WHERE ... LIKE '%' + @somehowEscapedMyString + '%'

匹配'aa%bb''caa%bbc'但没有'aaxbb''caaxbb'

Answers:


94

要在LIKE表达式中转义特殊字符,请在它们前面加上转义字符。您可以选择与ESCAPE关键字一起使用的转义字符。(MSDN参考

例如,使用\作为转义字符,可以转义%符号:

select * from table where myfield like '%15\% off%' ESCAPE '\'

如果您不知道字符串中将包含哪些字符,并且不想将其视为通配符,则可以在所有通配符前面加上转义字符,例如:

set @myString = replace( 
                replace( 
                replace( 
                replace( @myString
                ,    '\', '\\' )
                ,    '%', '\%' )
                ,    '_', '\_' )
                ,    '[', '\[' )

(请注意,您也必须转义转义字符,并确保这是内部字符,replace以免转义从其他replace语句添加的转义字符)。然后,您可以使用以下内容:

select * from table where myfield like '%' + @myString + '%' ESCAPE '\'

还要记住为@myString变量分配更多的空间,因为随着字符串替换它会变长。


目前,我正在使用stackoverflow.com/questions/13861004/…中提到的方法。您是否看到该代码有任何缺点?
LCJ 2012年

2
@Lijo,很好。该答案可以在C#中进行转义,而上述答案可以在SQL中进行,因为它不是特定于C#的。两种方法的结果都是相同的:在搜索字符串中转义任何特殊字符,并在LIKE语句中使用ESCAPE关键字。
罗里

我认为您还需要转义一个单引号(用两个单引号而不是代替\')。
泰德·霍普

@TedHopp-不,您不需要'出于LIKE的目的而逃脱,因为它不是LIKE的特殊字符。例如,这可以正常工作:declare @s nvarchar(max); set @s = '%''%'; with a_cte as ( select 'I''m adam' as aColumn ) select * from a_cte where aColumn like @s;
Rory

@TedHopp-您可能要指的是只需要使用两个即可'在字符串常量中定义单引号。是的,您需要这样做,但是结果字符串值仅包含一个单引号:进行转义只是为了在将其声明为常量值时将其添加到字符串变量中。您可以'从某个地方选择,而无需对其进行转义。
罗里2014年

19

遇到类似的问题(使用NHibernate,因此ESCAPE关键字将非常困难),并使用方括号字符解决了该问题。所以你的样本会变成

WHERE ... LIKE '%aa[%]bb%'

如果您需要证明:

create table test (field nvarchar(100))
go
insert test values ('abcdef%hijklm')
insert test values ('abcdefghijklm')
go
select * from test where field like 'abcdef[%]hijklm'
go

1
这是最好的答案。不依赖于转义,并且适用于所有字符串。
约翰

我认为这是最简单的方法,因此最接近申请者所要寻找的东西。并不是说ESCAPE在某些情况下没有用。
bitoolean

2
仍然没有任何关于如何可靠地获取需要转义的字符列表或如何获取任意字符串并将其正确转义的解释。
宾基

14

假设您在模式中使用了前导通配符,则比起转义字符串中对模式语法特别重要的所有字符,它更快捷,更轻松。

SELECT * 
FROM YourTable
WHERE CHARINDEX(@myString , YourColumn) > 0

如果您不使用前导通配符,则应避免上述方法,但是,由于它不能在 YourColumn

此外在情况下,最佳的执行计划将根据当使用估计可能是更好的匹配的行数而变化LIKE与方形支架相比时逸出语法两者CHARINDEX所述ESCAPE关键字


优秀!但是,如果没有领先的通配符怎么办?
科林

1
@Colin-如果没有前导通配符,并且目标是转义字符串中其他位置的所有通配符,那么您可以使用=代替。转义特殊字符答案对于查找以特定值开头的值的查询仍然有用,尽管LIKE在这种情况下可以使用索引,但CHARINDEX不能。
马丁·史密斯


3

您是否要查找包含转义符的字符串?例如,您想要这样:

select * from table where myfield like '%10%%'.

您想在哪里搜索10%的所有字段?如果是这种情况,则可以使用ESCAPE子句指定转义字符并转义通配符。

select * from table where myfield like '%10!%%' ESCAPE '!'

我在问题中添加了一个示例。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.