SQL Server 2016特殊(国别)字符检测异常问题求助
解决SQL Server中LIKE无法捕获国别字符(如á)的问题
这个问题的核心原因是SQL Server默认排序规则不区分重音,导致á这类带重音的字符被视为和普通a等价,所以你的[^a-zA-Z0-9 ]字符类无法匹配到它们。下面是两种可行的解决技巧:
方法1:使用区分重音的排序规则进行匹配
在LIKE语句后添加COLLATE子句,指定一个**区分重音(Accent-Sensitive,后缀为AS)**的排序规则,让SQL Server将带重音的字符视为独立于普通字母的存在。
修改后的查询示例:
;WITH cte AS ( SELECT 'Euro a€' St UNION SELECT 'adgkjb$' St UNION SELECT 'Bravo Endá' St ) SELECT * FROM cte WHERE St LIKE '%[^a-zA-Z0-9 ]%' COLLATE SQL_Latin1_General_CP1_CS_AS
这里用的SQL_Latin1_General_CP1_CS_AS是区分大小写和重音的排序规则,如果不需要区分大小写,可以换成SQL_Latin1_General_CP1_CI_AS(仅区分重音)。
方法2:通过UNICODE编码值判断字符
如果不想依赖排序规则,也可以直接检查每个字符的UNICODE编码值,过滤掉不在a-z、A-Z、0-9和空格范围内的字符。
SQL Server 2016支持STRING_SPLIT(需兼容级别≥130),可以用它拆分字符串逐个检查:
;WITH cte AS ( SELECT 'Euro a€' St UNION SELECT 'adgkjb$' St UNION SELECT 'Bravo Endá' St ) SELECT * FROM cte WHERE EXISTS ( SELECT 1 FROM STRING_SPLIT(St, '') WHERE VALUE <> '' AND UNICODE(VALUE) NOT BETWEEN 48 AND 57 -- 匹配0-9 AND UNICODE(VALUE) NOT BETWEEN 65 AND 90 -- 匹配A-Z AND UNICODE(VALUE) NOT BETWEEN 97 AND 122 -- 匹配a-z AND UNICODE(VALUE) <> 32 -- 匹配空格 )
如果你的数据库兼容级别低于130,可以用递归CTE来拆分字符串,效果是一样的。
补充说明
- 你当前使用的美国默认排序规则(如
SQL_Latin1_General_CP1_CI_AI)里的AI代表Accent-Insensitive(不区分重音),这就是为什么á会被当作a处理的原因。 - 如果你的列是
NVARCHAR类型,建议使用支持Unicode的排序规则(如Latin1_General_100_CI_AS_SC),避免字符编码问题。
内容的提问来源于stack exchange,提问作者Mike S
相关产品推荐
相关产品推荐

