patindex不支持正则表达式,仅识别like风格通配符(%、_、[abc]等);pattern通常须带%才能正确匹配子串;其条件难走索引,大小写行为取决于列排序规则,null输入返回null。

PATINDEX 不支持正则表达式,它只认 SQL Server 的 LIKE 风格通配符:%、_、[abc]、[^0-9] 等。所谓“正则匹配”是常见误解——你写 PATINDEX('^[0-9]+$', col) 会直接报错或永远返回 0,因为 ^、+、$ 这些正则元字符在 PATINDEX 里完全无效。
-
%匹配零个或多个任意字符(不是“.*”) -
_匹配且仅匹配一个任意字符(不是“.”) -
[0-9]表示字符类,等价于“任一数字字符”,不是“一个或多个数字” -
[^a-z]表示“非小写字母”,但不能写成[^a-z]<em></em>—— 不被识别
真正想做正则,SQL Server 2016+ 可用 CLR 自定义函数,或 SQL Server 2022+ 的 STRING_SPLIT + 多层逻辑拼接,但原生 PATINDEX 永远不解析正则语法。
几乎所有实际使用场景中,pattern 两边都必须带 %,否则匹配行为极不可靠:
-
PATINDEX('abc%', @text)→ 返回 0(哪怕 @text = 'abcdef'),因为 PATINDEX 要求 pattern 是完整模式表达式,开头没%就等价于“必须从字符串开头严格匹配”,但又不支持锚定(不像正则的 ^),结果就是失效 - 正确写法只有:
PATINDEX('%abc%', @text)(含子串)、PATINDEX('abc%', @text)(仅当明确要“以 abc 开头”且接受该语义时才可能生效,但实测多数版本仍返回 0) - 特殊情况:查“是否以某字符开头”应改用
LEFT(expression, 1) = 'x'或expression LIKE 'x%',别硬套 PATINDEX
常见错误包括:
- 忘记开头或结尾的
%,比如写成PATINDEX('[0-9]', col)→ 只匹配整个字段恰好等于一个数字的记录 - 把字符类当量词用,比如
'%[0-9][0-9]%'表示“连续两个数字”,可行;但'%[0-9]{2}%'会直接报错({2} 是正则语法,PATINDEX 不认) - 在变量拼接时漏掉
%:PATINDEX(@pattern, col)若 @pattern 值为 'abc',结果永远为 0;必须确保 @pattern 值本身含%,例如SET @pattern = '%' + @keyword + '%'
PATINDEX 条件基本无法走索引,执行计划里通常显示为 Clustered Index Scan 或 Table Scan:
- 即使列上有索引,
PATINDEX('%abc%', col) > 0也无法利用 B-tree 索引的有序性 - 若高频查询需加速,可建计算列(如
has_digit AS CASE WHEN PATINDEX('%[0-9]%', col) > 0 THEN 1 ELSE 0 END PERSISTED)再对该列建索引 - 大小写行为取决于列的排序规则(collation):
username列若用Latin1_General_CI_AS,则PATINDEX('%aBc%', username)能匹配 "ABC";若为_CS_AS或_BIN,则区分大小写,此时可显式转换:PATINDEX('%abc%', LOWER(username))
最易被忽略的一点:NULL 输入直接返回 NULL,不是 0。如果 expression 列允许 NULL,WHERE PATINDEX('%x%', col) > 0 会自动过滤掉 NULL 行(因为 NULL > 0 是 UNKNOWN),但若逻辑里需要显式处理 NULL,得加 OR col IS NULL 或用 ISNULL(col, '') 包裹。











