SQL Server 2008 R2
create table #test (c1 nvarchar(5) not null)
insert into #test values
(N'aaa'),
(nchar(65533)),
(N'bbb')
select * from #test where c1 like N'%�%'
select * from #test where c1 like N'%'+nchar(65533)+N'%'
结果是
c1
----
aaa
�
bbb
为什么?我还没有在 MSDN 中找到关于这个案例的任何说明。
最佳答案
该字符(以及许多其他字符,取决于所使用的排序规则版本)恰好没有定义排序权重。它实际上什么都不是。因此,无论您有 1 个还是 100 个实例,它对二进制排序规则以外的任何东西都是不可见的。意思是,以下WHERE
谓词:
LIKE N'%' + NCHAR(0xFFFD) + N'%'
LIKE N'%' + NCHAR(0xFFFD) + NCHAR(0xFFFD) + N'%'
LIKE N'%' + NCHAR(0xFFFD) + NCHAR(0xFFFD) + NCHAR(0xFFFD) + N'%'
等等,都等价于以下内容:
LIKE N'%%'
这就是为什么您返回所有 3 行的原因。
这并不意味着这个字符应该没有排序权重。它实际上在 Unicode 中被定义为具有权重,但出于某种原因,微软留下了相当多的字符根本没有任何排序权重(尽管每一个新的排序规则版本,缺少排序权重的字符总数都在减少,最新的是版本
140
排序规则,随 SQL Server 2017 一起提供,仅适用于日语排序规则)。对于没有排序权重的任何字符,匹配它的唯一方法是使用二进制排序规则。二进制排序规则是以
_BIN
结尾的排序规则或 _BIN2
,但只能使用 _BIN2
排序规则,因为它们排序正确,而较旧的 _BIN
校对没有。例如:SELECT * FROM #test WHERE c1 LIKE N'%�%' COLLATE Latin1_General_100_BIN2;
返回:
c1
----
�
另外,我使用以下内容进行了测试,它们返回了所有 3 行:
所以,以下应该是好的:
此外,最好使用可用于您尝试使用的排序规则的最高排序规则版本。例如,使用
Latin1_General_100_*
而不是 Latin1_General_*
, 等等。使用以下查询查找您的实例上可用的排序规则:SELECT col.*
FROM sys.fn_helpcollations() col
ORDER BY col.[name];
关于sql-server - LIKE 忽略魔法 Unicode 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27554244/