使用sql参数转义SQL LIKE语句中的特殊字符

我有一个包含产品的表。 我需要查询查找所有匹配结果到用户输入值。 我正在使用SqlParameter来插入输入。

 SqlCommand findProcutsByPattern = new SqlCommand( "SELECT *" + " FROM [Products]" + " WHERE ProductName LIKE @pattern", connection); findProcutsByPattern.Parameters.AddWithValue("@pattern", '%' + pattern + '%'); 

当用户输入字符串包含’_’或’%’时,问题就出现了,因为它们被解释为特殊字符。 另一方面,考虑到这一点:

命令对象使用参数将值传递给SQL语句或存储过程,从而提供类型检查和validation。 与命令文本不同,参数输入被视为文字值,而不是可执行代码。

我不应该有这样的问题。 我是否需要替换/转义输入字符串中的所有’_’和’%’,或者是否有更优雅的解决方案。 我希望输入被视为文字。

我在表中有一些记录,其中包括名称中的特殊字符(N_EW,N \ EW,N%EW,N“EW,N’EW)。指定\作为输入工作正常(考虑它们)作为文字)。

你有两个选择:

  • 将它们包含在[] 。 所以:

     where pattern like '[%]' 

    查找百分比字符。 要转义的完整字符列表 – '_', '%', '[', ']'以及相应的替换'[_]', '[%]', '[[]', '[]]' 。 可以在Escaping中找到示例代码, 转义字符不起作用 – SQL LIKE运算符

  • 使用不太可能在字符串中的转义字符,例如反引号:

     where pattern like '`%' escape '`' 

    (请参阅MSDN上的语法 – LIKE(Transact-SQL) 。)

在这两种情况下,我建议您在应用程序层中进行替换,但如果您真的需要,也可以在SQL中执行:

 where pattern like replace(@pattern, '%', '[%]') 

并且,在用户界面方面,让最终用户访问通配符可能是一件好事。


注意:LIKE查询中还有一些特殊字符'-''^' ,但如果您已经转义'['']'则不需要对它们进行转义。

一般来说,在SQL中手动转义值被认为是不好的做法,因为使用参数是首选(也是更安全)的解决方案。

但是,在您的示例中,您已经在使用参数并且想要使用LIKE运算符,因此手动转义字符应该没问题。 不要忘记转义转义字符 – 请参阅https://stackoverflow.com/a/13861567/232175以获取一些代码。

您可以这样做:在SQL字符串中指定显式转义字符,然后将该转义放在用户输入的字符串内的所有%_字符前面:

 SqlCommand findProcutsByPattern = new SqlCommand( @"SELECT * FROM [Products] WHERE ProductName LIKE @pattern", connection) ESCAPE '_'" 

设置参数时,将_%所有实例替换为___%

 var escapedPattern = Regex.Replace(pattern, "[%_]", "_$0"); 

演示。

所以,基本上,我手动转义(替换)所有的通配符,现在似乎工作正常。 这是最终的代码。

  SqlCommand findProcutsByPattern = new SqlCommand( "SELECT *" + "FROM [Products]" + "WHERE ProductName LIKE @pattern", connection); string patternEscaped = pattern.Replace("_", "[_]"); patternEscaped = patternEscaped.Replace("%", "[%]"); patternEscaped = patternEscaped.Replace("[", "[[]"); findProcutsByPattern.Parameters.AddWithValue("@pattern", '%' + patternEscaped + '%'); 

谢谢你的支持!

更新:我明白了……

escape_character是一个放在通配符前面的字符,表示通配符应该被解释为常规字符而不是通配符。 escape_character是一个没有默认值的字符表达式,必须只计算一个字符。

所以你仍然必须自己逃避。