【问题标题】:How can I escape square brackets in a LIKE clause?如何在 LIKE 子句中转义方括号?
【发布时间】:2010-10-01 04:03:52
【问题描述】:

我正在尝试使用 like 过滤带有存储过程的项目。该列是 varchar(15)。我要过滤的项目名称中有方括号。

例如:WC[R]S123456

如果我执行LIKE 'WC[R]S123456',它不会返回任何内容。

我找到了一些关于使用 ESCAPE 关键字和 LIKE 的信息,但我不明白如何使用它将方括号视为常规字符串。

【问题讨论】:

    标签: sql-server tsql escaping character sql-like


    【解决方案1】:
    LIKE 'WC[[]R]S123456' 
    

    LIKE 'WC\[R]S123456' ESCAPE '\'
    

    应该可以。

    【讨论】:

    • 如果要使用自定义转义字符,则需要 ESCAPE 关键字(反斜杠确实是自定义的)。
    • 我也更正了答案的另一部分。 SQL Fiddle with before and after versions
    • 如果有人不清楚为什么需要转义括号,documentation for LIKE 表示它用于匹配范围或集合中的单个字符。例如,使用 LIKE '[fz]oo' 将匹配 'foo' 和 'zoo'。
    • 在答案中为这两个方面提供理由会很好。在我阅读下面 Amitesh 的答案之前,我并没有立即明白为什么第一个示例会起作用。
    • 首选LIKE 'WC\[R]S123456' ESCAPE '\',因为它更便于维护。
    【解决方案2】:

    假设您要匹配文字 its[brac]et

    ] 不需要转义,因为它只有在与[ 配对时才具有特殊含义。

    因此转义[ 足以解决问题。您可以转义[ 将其替换为 [[]

    【讨论】:

    • 这真的很有帮助,而且 imo 是最好的答案。
    • [[] 确实看起来很奇怪,但是从解析器的角度来看它是有道理的。解析器对如何处理[ ] 之间的字符有一个特定的规则。因此,文本its[brac]et 的意思是:“查找以下连续字符串:its,(应用方括号规则:brac),et。另一方面,its[[]brac]et 表示:“查找以下连续字符串:its,(方括号应用规则:[),brac]et
    【解决方案3】:

    我需要从查询中排除以下划线开头的名称,所以我最终得到了这个:

    WHERE b.[name] not like '\_%' escape '\'  -- use \ as the escape character
    

    【讨论】:

    • 我必须使用这个版本(明确指定“转义”字符)——这里的其他答案没有给我正确的结果。
    【解决方案4】:

    这是我实际使用的:

    like 'WC![R]S123456' ESCAPE '!'
    

    【讨论】:

      【解决方案5】:

      如果您需要搜索 % 和 _ 等通常是通配符的特殊字符,则使用 E​​SCAPE 关键字。如果指定 ESCAPE,SQL 将按字面意思搜索字符 % 和 _。

      Here's a good article with some more examples

      SELECT columns FROM table WHERE 
          column LIKE '%[[]SQL Server Driver]%' 
      
      -- or 
      
      SELECT columns FROM table WHERE 
          column LIKE '%\[SQL Server Driver]%' ESCAPE '\'
      

      【讨论】:

        【解决方案6】:

        如果您需要转义特殊字符,如 '_'(下划线),就像我的情况一样,并且您不愿意/不能定义 ESCAPE 子句,您可能希望用方括号 '['']' 将特殊字符括起来。

        这解释了“奇怪”字符串 '[[]' 的含义 - 它只是将 '[' 字符包含在方括号中,有效地将其转义。

        我的用例是指定带有下划线的存储过程的名称作为 Profiler 的过滤条件。因此,我将字符串 '%name[_]of[_]a[_]stored[_]procedure%' 放在 TextData LIKE 字段中,它给了我想要实现的跟踪结果。

        这是文档中的一个很好的示例: LIKE (Transact-SQL) - Using Wildcard Characters As Literals

        【讨论】:

          【解决方案7】:

          根据documentation

          您可以使用通配符模式匹配字符作为文字 人物。要将通配符用作文字字符, 将通配符括在括号中。

          这三个字符需要转义%_[:

          '5%'      LIKE '5[%]'      -- true
          '5$'      LIKE '5[%]'      -- false
          'foo_bar' LIKE 'foo[_]bar' -- true
          'foo$bar' LIKE 'foo[_]bar' -- false
          'foo[bar' LIKE 'foo[[]bar' -- true
          'foo]bar' LIKE 'foo]bar'   -- true
          

          【讨论】:

            【解决方案8】:

            您也可以使用键盘上没有的特殊字符来代替“\”或键盘上的其他字符。根据您的用例,如果您不希望用户输入意外用作转义字符,这可能是必要的。

            【讨论】:

            • 我经常使用¬——它在英国仍然是一个键盘字符,但很少有人故意使用它:)(左上角在EscTab之间)
            • 用户仍然可以提交包含不在键盘上的字母的数据。这个答案听起来像是一个避免实际解决问题的建议……
            【解决方案9】:

            此时有一个问题:

            LIKE 'WC[[]R]S123456' 
            

            和:

            LIKE 'WC\[R]S123456' ESCAPE '\'
            

            两者都适用于 SQL Server,但都不适用于 Oracle。

            似乎没有 ISO/IEC 9075 方法来识别涉及左大括号的模式。

            【讨论】:

            • 大括号:{ 括号:[ 括号:(
            【解决方案10】:

            使用关注。

            对于要按原样搜索的用户输入,请使用转义,因为它需要以下替换所有特殊字符(以下涵盖所有 SQL Server)。

            这里不采用单引号“'”,因为它不影响like子句,因为它是字符串连接的问题。

            “-”和“^”和“]”替换不是必需的,因为我们正在转义“[”。

            String FormattedString = "UserString".Replace("ð","ðð").Replace("_", "ð_").Replace("%", "ð%").Replace("[", "ð[");
            

            那么,在 SQL Query 中应该如下所示。 (在参数化查询中,字符串可以在上述替换后添加模式)。

            搜索确切的字符串。

            like 'FormattedString' ESCAPE 'ð'
            

            从字符串开始搜索

            like '%FormattedString' ESCAPE 'ð'
            

            以字符串结尾

            like 'FormattedString%' ESCAPE 'ð'
            

            用字符串搜索包含

            like '%FormattedString%' ESCAPE 'ð'
            

            等等其他模式匹配。但是直接用户输入需要按照上面提到的格式进行。

            【讨论】:

              猜你喜欢
              • 2015-09-25
              • 1970-01-01
              • 2011-01-30
              • 2023-01-26
              • 2019-09-29
              • 2011-03-01
              • 1970-01-01
              • 2014-05-10
              • 1970-01-01
              相关资源
              最近更新 更多