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

时间:2008-11-03 14:24:11

标签: sql-server tsql stored-procedures sql-like

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

假设我有一个NVARCHAR变量,如下所示:

declare @myString NVARCHAR(100);

我希望在LIKE表达式中使用它:

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

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

例如,给定:

@myString = 'aa%bb'

我想:

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

匹配'aa%bb''caa%bbc'但不匹配'aaxbb''caaxbb'

6 个答案:

答案 0 :(得分:90)

要转义LIKE表达式中的特殊字符,请在其前面加上转义字符。您可以选择使用ESCAPE关键字的转义字符串。 (MSDN Ref

例如,这会转义%符号,使用\作为转义字符:

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变量分配更多空间,因为它会随着字符串替换而变得更长。

答案 1 :(得分:18)

有类似的问题(使用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

答案 2 :(得分:13)

在字符串中转义所有字符时,如果您在模式中使用了前导通配符,那么在模式语法中具有特殊意义,而不是仅仅这样做。

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

如果您没有使用前导通配符,则应避免使用上述方法,因为它无法在YourColumn上使用索引。

此外,如果最佳执行计划会根据匹配行的数量而有所不同,那么与both CHARINDEX和{{3]相比,使用带有方括号转义语法的LIKE时,估算可能会更好}}

答案 3 :(得分:4)

答案 4 :(得分:3)

您想查找包含转义字符的字符串吗?例如,你想要这个:

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

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

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

答案 5 :(得分:0)

其他转义语法:

  

LIKE Wildcard Literals

     

JDBC驱动程序支持 {escape'escape character'} 语法,以将LIKE子句通配符用作文字。

SELECT *
FROM tab
WHERE col LIKE 'a\_c' {escape '\'};

db<>fiddle demo