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

本文关键字:SQL 特殊字符 语句 LIKE 参数 转义 使用 | 更新日期: 2023-09-27 18:21:06

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

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

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

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

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

我在表中有一些记录,其中包括名称中的特殊字符(N_EW、N''EW、N+EW、N"EW、N/EW)。指定''"'作为输入很好(将它们视为文字)。

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

您有两个选项:

  • 将它们封装在CCD_ 2和CCD_。因此:

    where pattern like '[%]'
    

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

  • 使用不太可能出现在字符串中的转义符,例如backtick:

    where pattern like '`%' escape '`'
    

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

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

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

而且,就用户界面而言,允许最终用户访问通配符可能是一件好事。


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

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

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

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

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

演示。

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

然而,在您的示例中,您已经在使用参数,并且希望使用LIKE运算符,因此手动转义字符应该是可以的。也别忘了逃离逃生角色-请参阅https://stackoverflow.com/a/13861567/232175获取一些代码。

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

        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是没有默认值且只能计算为一个的字符表达式性格

所以你还是得自己逃跑。