SQL LIKE子句的特殊字符列表

138

如何获取 SQL(我对 SQL Server 特别感兴趣,但其他数据库也行)LIKE 条件下所有特殊字符的完整列表?

例如:

SELECT Name FROM Person WHERE Name LIKE '%Jon%'

SQL Server:

  1. % - 任意零个或多个字符。
  2. _ - 任意单个字符。
  3. [specifier] 比如 [a-z]。
  4. [^specifier]
  5. ESCAPE子句,例如 %30!%%' ESCAPE '!' 会把 30% 作为真值处理。
  6. ' 字符需要用 '' 转义,例如 they're 变成 they''re。

MySQL:

  1. % - 任意零个或多个字符。
  2. _ - 任意单个字符。
  3. ESCAPE子句,例如 %30!%%' ESCAPE '!' 会把 30% 作为真值处理。

Oracle:

  1. % - 任意零个或多个字符。
  2. _ - 任意单个字符。
  3. ESCAPE子句,例如 %30!%%' ESCAPE '!' 会把 30% 作为真值处理。

Sybase

  1. % - 任意零个或多个字符。
  2. _ - 任意单个字符。
  3. [specifier] 比如 [a-z]。
  4. [^specifier]

Progress:

  1. % - 任意零个或多个字符。
  2. _ - 任意单个字符

    参见此处的参考指南 [PDF]

PostgreSQL:

  1. % - 任意零个或多个字符。
  2. _ - 任意单个字符。
  3. 使用ESCAPE clause,例如 %30!%%' ESCAPE '!' 将把30%评估为true。

ANSI SQL92:

  1. %
  2. _
  3. 只有在指定时才会有一个ESCAPE字符。

PostgreSQL还有SIMILAR TO操作符,它添加了以下内容:

  1. [specifier]
  2. [^specifier]
  3. | - 两个备选项中的任何一个
  4. * - 重复前面的项目零次或多次。
  5. + - 重复前面的项目一次或多次。
  6. () - 将项目组合在一起

这个想法是将其打造成一个社区Wiki,成为“一站式”服务。


值得一提的是,ESCAPE 子句。SQL Server、Oracle 和 MySQL 都支持此功能,不确定 Sybase 是否支持。 - David Webb
我现在认为,ESCAPE子句是标准SQL,因此可能只需要提及一次。 - David Webb
我自己不知道它是否在所有列出的服务器(以及可能添加的任何服务器)中实现,因此我不愿将其提取到“所有支持”部分。如果您确信它们都受支持,请继续。 - Jonathan Parker
不要忘记转义转义字符本身... - Christoffer Hammarström
1
两个注释。首先,微软SQL最初来自Sybase,因此相似性并非巧合。其次,用另一个单引号转义单引号不仅限于LIKE;例如WHERE familyname = 'O''Toole'。第三,SIMILAR TO运算符引入了一种混合正则表达式,具有其自身的特点(和更多特殊字符),因此可能不应包括在此处。我猜这就是3个评论,但没有人会预料到西班牙宗教裁判所。 - Manngo
5个回答

27

针对 SQL Server,来自 http://msdn.microsoft.com/en-us/library/ms179859.aspx

  • % 代表零个或多个字符。

    WHERE title LIKE '%computer%' 查找所有书名中包含单词“computer”的图书标题。

  • _ 代表任意单个字符。

    WHERE au_fname LIKE '_ean' 查找以 ean 结尾的所有四个字母的名字 (例如 Dean、Sean 等)。

  • [ ] 代表指定范围 ([a-f]) 或集合 ([abcdef]) 中的任意单个字符。

    WHERE au_lname LIKE '[C-P]arsen' 查找以 arsen 结尾且以 C 到 P 范围内的任意单个字符开头的作者姓氏,例如 Carsen、Larsen、Karsen 等。在范围搜索中,被包括在范围内的字符可能会因排序规则而有所不同。

  • [^] 代表非指定范围 ([^a-f]) 或集合 ([^abcdef]) 中的任意单个字符。

    WHERE au_lname LIKE 'de[^l]%' 查找所有以 de 开头且后面一个字母不是 l 的作者姓氏。


1
我刚试了一下,看起来是可以的。但它不像正则表达式 => [0-9] 那样简单。相反,你需要像这样指定每个字符:[0123456789]。 - Çağdaş Tekin
4
等等,不对。这就像正则表达式,所以 [0-9] 也可以工作。抱歉让你感到困惑。 - Çağdaş Tekin

6

ANSI SQL92

  • %
  • _
  • 只有在指定时才有转义字符

令人失望的是,许多数据库没有遵循标准规则,添加了额外的字符,或者在缺少时错误地启用了默认值为“\”的转义字符。就像我们已经有足够的麻烦一样,不需要再加上‘\’!

这里无法编写与DBMS无关的代码,因为您不知道要转义哪些字符,而且标准规定您不能转义不需要转义的内容(请参见第8.5节/常规规则/3.a.ii)。

感谢SQL!gnnn


5
您需要添加另一个单引号来转义 SQL Server 中已存在的单引号:

smith's -> smith''s


1

Sybase:

%              : Matches any string of zero or more characters.
_              : Matches a single character.
[specifier]    : Brackets enclose ranges or sets, such as [a-f] 
                 or [abcdef].Specifier  can take two forms:

                 rangespec1-rangespec2: 
                   rangespec1 indicates the start of a range of characters.
                   - is a special character, indicating a range.
                   rangespec2 indicates the end of a range of characters.

                 set: 
                  can be composed of any discrete set of values, in any 
                  order, such as [a2bR].The range [a-f], and the 
                  sets [abcdef] and [fcbdae] return the same 
                  set of values.

                 Specifiers are case-sensitive.

[^specifier]    : A caret (^) preceding a specifier indicates 
                  non-inclusion. [^a-f] means "not in the range 
                  a-f"; [^a2bR] means "not a, 2, b, or R."

0

SQL Server的潜在解决方案

有趣的是,我刚刚使用了LinqPad和SQL Server运行了一个测试,应该只在运行Linq to SQL,并生成以下SQL语句。

记录     .Where(r => r.Name.Contains(“lkjwer--_〜[]”))

-- Region Parameters
DECLARE @p0 VarChar(1000) = '%lkjwer--~_~~~[]%'
-- EndRegion
SELECT [t0].[ID], [t0].[Name]
FROM [RECORDS] AS [t0]
WHERE [t0].[Name] LIKE @p0 ESCAPE '~'

所以我还没有测试过,但看起来可能 ESCAPE '~' 关键字可以自动转义字符串以在 like 表达式中使用。


他们可能只是使用ESCAPE,因为它允许每个转义字符使用两个字符(例如,变成〜%),而不是三个字符(例如,如果没有ESCAPE,则变成%[])。 - binki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接