LIKE '%1%' 最快最可靠,因其用T-SQL否定字符集一次性匹配所有非字母数字字符,无需枚举或OR拼接,兼容SQL Server 2005+,不依赖函数或权限,且正确处理中文排序下ASCII边界,兼顾性能与通用性。a-zA-Z0-9 ↩

直接结论:用 LIKE '%[^a-zA-Z0-9]%' 最快、最可靠,但必须注意字符集和边界定义。
为什么 LIKE '%[^a-zA-Z0-9]%' 是首选
它利用 T-SQL 的字符范围否定语法 [^...],一次性匹配所有非字母数字字符,无需逐个枚举或拼接多个 OR 条件。执行计划简单,索引虽无法直接加速该模式(因前导通配符),但比循环或 CLR 更轻量。
- 适用于绝大多数「只允许英文、数字」的校验场景(如用户名、编码字段)
- 不依赖额外函数或权限,所有 SQL Server 版本(2005+)都支持
- 注意:
a-zA-Z0-9默认按数据库排序规则比较;若库为中文排序(如Chinese_PRC_CI_AS),[^a-zA-Z0-9]仍只排除 ASCII 字母数字,不会误判中文、日文等——这点常被忽略 - 若需允许下划线
_或连字符-,写成[^a-zA-Z0-9_-],但记得把-放在末尾,否则会被解析为范围符
LIKE 中特殊字符要转义吗?什么时候必须加 ESCAPE
只有当你想**字面匹配** [、]、%、_ 这几个通配符本身时,才需要转义。检测「是否含特殊字符」本身不需要转义——因为你在用 [^...] 定义字符集,不是在匹配单个符号。
- 错误写法:
LIKE '%[\!@\#\$]%'——这只会查!、@、#、$四个字符,漏掉其余几十种 - 正确写法:
LIKE '%[^a-zA-Z0-9]%',不用ESCAPE - 真要查字面
[:写成LIKE '%\[%' ESCAPE '\';查字面%:写成LIKE '%\%%' ESCAPE '\' - 如果特殊字符列表固定且较短(比如只禁
;、、|~),也可用LIKE '%[;|~]%',但维护性差
PATINDEX 和 CHARINDEX 的适用差异
PATINDEX 支持通配符模式(如 '%[^a-zA-Z0-9]%'),CHARINDEX 只支持字面子串。所以检测「任意特殊字符」只能用 PATINDEX,不能用 CHARINDEX('!', col) > 0 OR CHARINDEX('@', col) > 0... 这种硬编码方式。
-
PATINDEX('%[^a-zA-Z0-9]%', @str) > 0返回1表示存在,返回0表示不存在 -
CHARINDEX适合查已知具体字符(如回车CHAR(13)、制表符CHAR(9)),写法是CHARINDEX(CHAR(13), col) > 0 - 性能上两者接近,但
PATINDEX多一次模式编译开销;对大数据量,建议先用LEN(col) > 0排除空值,再进模式匹配
容易被忽略的边界情况
真正上线后出问题的,往往不是语法,而是语义没对齐:
- 空格
、制表符CHAR(9)、换行CHAR(10)、回车CHAR(13)都属于[^a-zA-Z0-9],但业务上可能允许空格——此时应显式排除:用[^a-zA-Z0-9 ](注意空格在括号内) - 全角字符(如全角数字、全角字母)ASCII 值不在 48–57 / 65–90 / 97–122 范围内,会被
[^a-zA-Z0-9]捕获,但它们未必是业务定义的「特殊字符」 -
NVARCHAR字段中可能出现CHAR(0)(空字符),它不可见,但LIKE和PATINDEX都能匹配到;若需排除,得单独加条件CHARINDEX(CHAR(0), col) = 0 - 排序规则为
_BIN或_BIN2时,大小写敏感且严格按码点比较,[^a-zA-Z0-9]行为不变,但要注意某些 Unicode 控制字符的码点位置
实际用的时候,先明确「哪些算特殊字符」——这个业务定义比技术实现更重要。一旦定义清楚,LIKE '%[^...]%' 就是最稳的那条路。其他方案要么太重(CLR),要么太散(一堆 OR),要么太窄(只查几个符号)。










