无法在NVARCHAR字段中存储特定的Unicode代码点/字符

问题描述 投票:1回答:2

我正在使用SQL Server 2017做一些测试。我正在尝试在NVARCHAR列中存储任意Unicode代码点。我尝试了不同的排序规则。我对Unicode的BMP平面中的常见字符没有任何问题。

对于更多的外来符号,例如,如果我尝试存储“𝌹”字符(U + 1D33),则会发生以下情况:

  • 如果在Management Studio中进行操作,则只会看到臭名昭著的方形符号。但是Management Studio具有正确的字体,因为我可以将其粘贴到查询编辑器中。
  • 如果我从Visual Studio发送文本,则在Management Studio中看到的值为“ ??”,这也是我在执行查询后从Visual Studio中检索到的值。

我的理解是,对于非补充字符排序规则,由于NCHAR字段限制为2个字节,因此不应正确解释UCS-2子集之外的字符。

但是,我在数据库级别和列级别都尝试了Latin1_General_100_CS_AS_KS_WS_SC,而且似乎也不起作用。

有什么想法吗?谢谢

sql-server tsql unicode ssms collation
2个回答
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;

我在网格中看到一个正方形,24。这意味着该字符已正确存储并占用了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。 他们显示汉字不会有任何问题。


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上确认了这一点。

有关更多信息,请参见:

© www.soinside.com 2019 - 2024. All rights reserved.