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

时间:2014-09-06 18:50:42

标签: c# sql sql-server escaping sqlparameter

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

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

findProcutsByPattern.Parameters.AddWithValue("@pattern", '%' + pattern + '%');

当用户输入字符串包含' _'或者'%'因为他们被解释为特殊字符。另一方面,考虑到这一点:

  

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

我不应该有这样的问题。我是否需要更换/逃避所有' _'和'%'在输入字符串中还是有更优雅的解决方案。我希望输入被视为文字。

我在表格中有一些记录,其中包括名称中的特殊字符(N_EW,N \ EW,N%EW,N" EW,N' EW)。指定 \ " ' ,因为输入正常(将其视为文字)。

4 个答案:

答案 0 :(得分:8)

您有两种选择:

  • 将其封在[]中。所以:

    where pattern like '[%]'
    

    查找百分比字符。 要转义的完整字符列表 - '_', '%', '[', ']'以及相应的替换'[_]', '[%]', '[[]', '[]]'。示例代码可在Escaping the escape character does not work – SQL LIKE Operator

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

    where pattern like '`%' escape '`'
    

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

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

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

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


注意:LIKE查询中还有一些特殊字符'-''^',但如果您已经转义'['和{{1},则无需转义它们}}

答案 1 :(得分:2)

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

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

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

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

Demo.

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

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

        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是放在通配符前面的字符   表示通配符应解释为a的字符   常规字符而不是通配符。 escape_character是一个   字符表达式没有默认值,必须只评估一个   字符。

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