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中找到关于此案例的任何说明。
答案 0 :(得分:2)
该角色(以及许多其他角色,取决于正在使用的归类版本)恰好没有定义排序权重。实际上没什么。因此,无论您有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中被定义为具有权重,但由于某种原因,Microsoft已经留下了相当多的字符而没有任何排序权重(尽管每个新的Collation版本缺少排序权重的字符总数正在减少,最新的是版本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];