Aus*_*Ash 5 sql-server collation encoding unicode
select * from (select N'?? ' as t) as t2 where t= ''
Run Code Online (Sandbox Code Playgroud)
字符串 '?? ' 匹配上面的检查,这是为什么?
Sol*_*zky 10
虽然我不确定这些特定字符的确切原因,但问题与较旧的排序规则有关(请参阅最后的更新部分)。它们不仅等同于空字符串,而且还等同于这些字符之一:
SELECT * FROM (SELECT N'??') tab(col) WHERE tab.col = N'?';
Run Code Online (Sandbox Code Playgroud)
如果您尝试区分大小写的排序规则,即使有多个字符,它们仍然等同于:
SELECT * FROM (SELECT N'??') t(c) WHERE t.c = N'????' COLLATE SQL_Latin1_General_CP1_CS_AS;
SELECT * FROM (SELECT N'?') t(c) WHERE t.c = N'????' COLLATE SQL_Latin1_General_CP1_CS_AS;
SELECT * FROM (SELECT N'?') t(c) WHERE t.c = N'????' COLLATE SQL_Latin1_General_CP1_CS_AS;
Run Code Online (Sandbox Code Playgroud)
即使是“等效的”Windows 排序规则也有同样的问题:
SELECT * FROM (SELECT N'??') t(c) WHERE t.c = N'?' COLLATE Latin1_General_CS_AS;
SELECT * FROM (SELECT N'??') t(c) WHERE t.c = N'?' COLLATE Latin1_General_CS_AS_KS_WS;
Run Code Online (Sandbox Code Playgroud)
但是,似乎较新版本的 Windows 排序规则(即 100 系列或更新版本)“修复”了该问题,而这些不再等同于:
SELECT * FROM (SELECT N'??') t(c) WHERE t.c = N'?' COLLATE Latin1_General_100_CI_AI;
SELECT * FROM (SELECT N'??') t(c) WHERE t.c = N'?' COLLATE Latin1_General_100_CI_AS;
Run Code Online (Sandbox Code Playgroud)
而且,当然,二进制 Windows 排序规则(旧的和新的系列)工作得很好,因为以下不报告匹配:
SELECT * FROM (SELECT N'??') t(c) WHERE t.c = N'?' COLLATE Latin1_General_BIN;
SELECT * FROM (SELECT N'??') t(c) WHERE t.c = N'?' COLLATE Latin1_General_BIN2;
SELECT * FROM (SELECT N'??') t(c) WHERE t.c = N'?' COLLATE Latin1_General_100_BIN;
SELECT * FROM (SELECT N'??') t(c) WHERE t.c = N'?' COLLATE Latin1_General_100_BIN2;
Run Code Online (Sandbox Code Playgroud)
UPDATE(2015年8月20日),
6小时后通过文档浇筑的http://www.unicode.org/,http://site.icu-project.org/,和其他几个Unicode相关的网站,我放弃了寻找可能在 2008 年之前发生的“权重”变化的证据(SQL Server 2008 中引入了新的 100 系列排序规则)。但是,我确实在www.fileformat.info 上找到了此处测试的两个字符的以下信息:
因此,我继续进行下一个项目,不久之后在 SQL Server 2008 MSDN 页面上的排序规则和 Unicode 支持中发现了以下内容:
SQL Server 2008 引入了与 Windows Server 2008 提供的排序规则完全一致的新排序规则。这 80 个新排序规则由 *_100 版本引用表示。它们为用户提供最新的、语言准确的文化分类惯例。支持包括以下内容:
- ...
- 已将权重添加到先前未加权的字符中,这些字符将进行同等比较。
字符没有排序权重意味着它实际上是不可见的。
故事寓意:不要那么努力;早点放弃;-)
更新 (2018-09-20)
为了更直观地显示正在发生的事情,下面的查询将每个 BMP 字符(代码点 0 - 65535 / U+0000 - U+FFFF)与一个空字符串进行比较。使用不同的排序规则重复比较:BIN2、SQL Server 排序规则、从 SQL Server 2000 开始的 Latin1_General、从 SQL Server 2008 开始的 Latin1_General、从 SQL Server 2008 开始的 Japanese_XJIS 和从 SQL Server 2017 开始的 Japanese_XJIS。这两个从 SQL Server 2008 开始的排序规则显示两者返回相同数量的匹配,但较新的 Japanese_XJIS 排序规则返回不同的数字(SQL Server 2017 中更新的唯一排序规则是日语排序规则)。这样做是为了显示在各种排序规则版本中有多少字符缺少排序权重。
;WITH nums AS
(
SELECT TOP (65536) (ROW_NUMBER() OVER (ORDER BY (SELECT 0)) - 1) AS [CodePoint]
FROM [master].[sys].[columns] col
CROSS JOIN [master].[sys].[objects] obj
)
SELECT nums.[CodePoint],
COALESCE(NCHAR(nums.[CodePoint]), N'TOTALS:') AS [Character],
COUNT(CASE WHEN (NCHAR(nums.[CodePoint]) = N''
COLLATE Latin1_General_BIN2) THEN 1 END) AS [BIN2],
COUNT(CASE WHEN (NCHAR(nums.[CodePoint]) = N''
COLLATE SQL_Latin1_General_CP1_CS_AS) THEN 1 END) AS [SQL Collations],
COUNT(CASE WHEN (NCHAR(nums.[CodePoint]) = N''
COLLATE Latin1_General_CS_AS_KS_WS) THEN 1 END) AS [SQL2000 Latin1],
COUNT(CASE WHEN (NCHAR(nums.[CodePoint]) = N''
COLLATE Latin1_General_100_CS_AS_KS_WS) THEN 1 END) AS [SQL2008 Latin1],
COUNT(CASE WHEN (NCHAR(nums.[CodePoint]) = N''
COLLATE Japanese_XJIS_100_CS_AS_KS_WS) THEN 1 END) AS [SQL2008 Japanese],
COUNT(CASE WHEN (NCHAR(nums.[CodePoint]) = N''
COLLATE Japanese_XJIS_140_CS_AS_KS_WS) THEN 1 END) AS [SQL2017 Japanese]
FROM nums
GROUP BY ROLLUP ((nums.[CodePoint], NCHAR(nums.[CodePoint])));
Run Code Online (Sandbox Code Playgroud)
要查看所有行的详细信息,请执行上面的查询。但对于总结来说,那就是:
BIN2 SQL Collations SQL2000 Latin1 SQL2008 Latin1 SQL2008 Japanese SQL2017 Japanese
1 21230 21229 5840 5840 3375
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1304 次 |
最近记录: |