Escaping special characters in a SQL LIKE statement using sql parameters

后端 未结 4 1114
小鲜肉
小鲜肉 2020-12-11 21:25

I have a table containing products. I need to make a query finding all the matching results to an user-input value. I am using SqlParameter for the insertion of

相关标签:
4条回答
  • 2020-12-11 21:58

    Generally speaking, manually escaping values in SQL is considered bad practice as using parameters is the preferred (and more secure) solution.

    In your example, however, you are already using parameters and you want to use the LIKE operator, so manually escaping the characters should be fine. Don't forget escaping the escape characters, too - see https://stackoverflow.com/a/13861567/232175 for some code.

    0 讨论(0)
  • 2020-12-11 22:00

    You have two options:

    • enclose them in [ and ]. So:

      where pattern like '[%]'
      

      Looks for the percentage character. Full list of characters to escape - '_', '%', '[', ']' with corresponding replacements '[_]', '[%]', '[[]', '[]]'. Sample code can be found in Escaping the escape character does not work – SQL LIKE Operator

    • use an escape character that is unlikely to be in the string, such as a backtick:

      where pattern like '`%' escape '`'
      

      (See the syntax on MSDN - LIKE (Transact-SQL).)

    In both cases, I would suggest that you make the substitution in the application layer, but you can also do it in SQL if you really want:

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

    And, giving the end-user access to wildcards may be a good thing in terms of the user interface.


    Note: there are couple more special characters '-' and '^' in the LIKE query, but they don't need to be escaped if you are already escaping '[' and ']'.

    0 讨论(0)
  • 2020-12-11 22:05

    So, basically, I manually escaped(replaced) all the wildcard symbols, which seems to work fine now. Here is the final code.

            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 + '%');
    

    Thank you for the support!

    UPDATE: I see...

    escape_character Is a character that is put in front of a wildcard character to indicate that the wildcard should be interpreted as a regular character and not as a wildcard. escape_character is a character expression that has no default and must evaluate to only one character.

    So you still have to do the escaping yourself.

    0 讨论(0)
  • 2020-12-11 22:23

    You can do it like this: specify an explicit escape character in your SQL string, and then place that escape in front of all % and _ characters inside the string the user enters:

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

    When you set the parameter, replace all instances of _ and % with __ and _%:

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

    Demo.

    0 讨论(0)
提交回复
热议问题