我正在使用SQL Server 2017做一些测试。 我试图在nvarchar列中存储任意unicode点。 我尝试了不同的排序规则。 我对Unicode的PBS平面中的常见字符没有问题。
对于更多的外来符号,例如,如果我尝试存储字符(U + 1D33),则会发生以下情况:
如果我在Management Studio中执行此操作,则只会看到臭名昭著的方形符号。但是Management Studio具有正确的字体,因为我可以将其粘贴到查询编辑器中。
如果我从Visual Studio发送文本,则在Management Studio中看到的值是“ ??”,这也是我在执行查询后从Visual Studio中检索到的值。
我的理解是,对于非补充字符排序规则,UCS-2子集之外的字符不应正确解释,因为nchar字段限制为2个字节。
但是我在数据库级别和列级别都尝试了Latin1_General_100_CS_AS_KS_WS_SC,但这似乎也不起作用。
有什么想法吗? 谢谢
答案 0 :(得分:1)
我无法重现任何数据丢失或编码问题。我可以复制复制后变成的正方形。这可能是由于 font 用于在SSMS网格或Visual Studio调试器窗口中显示结果所致。
SQL Server和Windows现在使用UTF16已有一段时间,而不是UCS-2。但是,很少有字体支持完整的UTF16范围。
当我在SSMS中尝试此操作时:
create table #tc(name nvarchar(20));
insert into #tc values (N'');
select name,len(name),DATALENGTH(name) from #tc;
我在网格中看到了一个正方形2
和4
。这意味着字符已正确存储并占用了4个字节。当我尝试将那些结果复制到SO时,虽然看到了:
name (No column name) (No column name)
2 4
当我使用Result to Text
时,我得到了实际的字符:
name
-------------------- ----------- -----------
2 4
有正确的字符,但SSMS网格的字体无法显示
更新
如Dan Guzman所言,可以从“工具”->“选项”->“环境”->“字体和颜色”->“显示以下设置:->网格结果”更改字体。默认字体为Microsoft Sans Serif,这是Windows上用作默认字体的小字体(855KB)。它包含“仅” 3000个字形。不包括汉字,这就是为什么显示正方形的原因。
尽管如此,中国计算机仍将SimShun作为默认文件,文件大小为17.1MB。 他们显示汉字不会有任何问题。
答案 1 :(得分:0)
我正在尝试在nvarchar列中存储任意unicode点。我尝试了不同的排序规则。我对Unicode的PBS平面中的常见字符没有问题。
排序规则与可以存储在NVARCHAR
/ NCHAR
/ NTEXT
(不推荐使用)列,变量或文字中的代码点无关。这些数据类型可以存储所有1,114,112个Unicode代码点(即使大多数尚未映射到字符)。
如果我尝试在Management Studio中存储?字符(U + 1D33),...,我只会看到臭名昭著的方形符号。但是Management Studio具有适当的字体,因为我可以将其粘贴到查询编辑器中。
正如其他人已经解释的那样:这仅仅是字体问题。字体最多可容纳65k个字符,因此您可能需要多种字体才能覆盖所有要使用的字符。我更喜欢在FontSpace.com上找到的Code2003。
如果我从Visual Studio发送文本,则在Management Studio中看到的值是'??'
这应该是由于忘记为字符串文字加上大写的“ N”;-)。
SELECT '?' AS [Oops], N'?' AS [No Oops];
-- ?? ?
我的理解是,对于非补充字符校对,由于nchar字段限制为2个字节,因此不应正确解释UCS-2子集之外的字符。
辅助字符识别(SCA)归类(名称中以_SC
或以_140_
结尾的字符)确实支持辅助字符。但是,“支持”仅表示内置函数将代理对作为单个补充代码点而不是一对代理代码点来处理。但是,实际上在SQL Server 2005中引入了版本90归类开始支持对补充字符进行排序和比较。
UCS-2和UTF-16中的所有代码单元均为16位/ 2字节。补充字符只是那些2字节代码单元中的两个。因此,当引入NVARCHAR
时,SQL Server 7.0应该已经可以使用补充字符存储功能。即使直到几年后(在SQL Server 2000发布之后)都没有定义补充字符,NVARCHAR
类型仍然可以存储和检索它们。我没有要测试的SQL Server 7.0,但是我已经在SQL Server 2000上确认了这一点。
有关更多信息,请参见: