【问题标题】:Should NVARCHAR be used to saved 'accented characters' into Sql Server?是否应该使用 NVARCHAR 将“重音字符”保存到 Sql Server 中?
【发布时间】:2020-01-08 00:40:56
【问题描述】:

我在 Sql Server 表中有以下两个字段:

当我在字段中添加一些带有重音字符的测试数据时,它实际上存储了它们!我以为我必须将列从 VARCHAR 更改为 NVARCHAR 才能接受重音字符等?

基本上,我认为:

  • VARCHAR = ASCII
  • NVARCHAR = Unicode

这是façadeare actually ASCII ..而某些其他字符会出错的情况(如果VARCHAR)?

我可以在 扩展 ASCII 图表中看到 çé 字符(上面的链接).. 这是否意味着 ASCII 包括 0->127 或 0->255?

(边想:我想我很高兴接受 0->255 并去掉其他任何东西。)

编辑

  • 数据库整理:Latin1_General_CI_AS
  • 服务器版本:12.0.5223.6
  • 服务器排序:SQL_Latin1_General_CP1_CI_AS

【问题讨论】:

  • 你需要有 NVARCHAR 数据类型。在保存数据时,您需要添加前缀 N' 以避免数据损坏。使用 : N'This home is in prime location...' 在插入和检查中
  • 感谢您的评论,但我认为您没有正确阅读我的问题?目前,数据类型是VARCHAR,目前,数据库正在存储那些重音字符。请重新阅读帖子以查看详细信息和我要问的问题。不过,感谢您阅读我的帖子:)
  • 抱歉没有准确阅读。如果我使用相同的 varchar 保存,则在我的区域语言中它不起作用。我现在需要阅读更多的 sql :)
  • 如果您在数据库中存储非 ASCII 数据,您绝对应该使用 nvarchar 列类型。使用varchar 列时,128-255 范围内的任何字符都受应用于数据库、表或特定列的COLLATION 设置的约束,并且在插入/更新时可能会被破坏。
  • @Pure.Krome 您要求的链接是关于代码页、ASCII 和 Unicode 的维基百科文章。不,ç 不是 ASCII,它不存在于 7 位 US-ASCII 代码页中。它存在于 other 代码页中,例如拉丁语 1。排序规则确实指定了用于处理存储文本的代码页。如果您在阅读时使用了错误的代码页,则会出现乱码。这是非常有据可查的。我怀疑您的数据库使用拉丁 1 排序规则,这就是您可以存储法语字符的原因。不过,您将无法存储希腊语或西里尔字符。

标签: sql-server unicode


【解决方案1】:

首先是 Sql Server 正在做什么的详细信息。

VARCHAR 使用特定的collation 存储单字节 个字符。 ASCII 仅使用 7 位,或一个字节中可能值的一半。排序规则引用特定的代码页(以及排序规则和相等规则)以使用每个字节中可能值的另一半。这些代码页通常包括对有限和特定重音字符集的支持。如果用于您的数据的代码页支持重音字符,您可以这样做;如果没有,您会看到奇怪的结果(无法打印的“框”或 ? 字符)。您甚至可以输出存储在一个排序规则中的数据,就好像它存储在另一个排序规则中一样,并以这种方式得到非常奇怪的东西(但不要这样做)。

NVARCHAR 是 unicode,但仍有一些对排序规则的依赖。在大多数情况下,您最终会得到UTF-16,它确实允许所有的unicode 字符。某些排序规则将改为生成 UCS-2,它的限制稍微多一些。请参阅nchar/nvarchar documentation 了解更多信息。

另外一个怪癖是,在使用正确的排序规则时,charvarchar 中即将出现的 Sql Server 2019 will include support for UTF-8 类型。


现在回答这个问题。

在极少数情况下,您确定您的数据只需要支持源自单一特定(通常是本地)文化的重音字符,并且那些特定的重音字符字符,您可以使用 varchar 类型。

但是要非常小心做出这个决定。在一个日益全球化和多样化的世界中,即使是小型企业也希望利用互联网来扩大其影响力,即使是在他们自己的社区内,使用不充分的编码很容易导致错误甚至安全漏洞。大多数看起来 varchar 编码可能已经足够好的情况实际上不再安全了。

就个人而言,我今天使用varchar 的唯一地方是助记符字符串,这些字符串从未向最终用户显示或提供;过程代码中可能是enum 值的东西。即使这样,这也往往是遗留代码,并且如果可以选择我将使用整数值来代替,以实现更快的连接和更有效的内存使用。但是,即将推出的 UTF-8 支持可能会改变这一点。

【讨论】:

  • 这是一个很好的答案@JoelCoehoorn - ta!排除新的 SqlServer 2019 + UTF-8 内容,这确实回答了我的问题:坚持使用 NVARCHAR 进行用户输入。我的用户是全球性的,所以我应该尊重这一点。干杯,非常感谢您的详细回答!
【解决方案2】:

VARCHAR 是使用当前系统代码页的 ASCII - 因此您可以保存的字符集取决于代码页。

NVARCHAR 是 UNICODE,因此您可以存储所有字符。

【讨论】:

  • 这很接近,但并不完全正确。代码页由表上的排序规则决定,而不是操作系统。
  • @JoelCoehoorn 也可以在字段级别被覆盖,这对于本地化字段很方便。
猜你喜欢
  • 1970-01-01
  • 2012-03-13
  • 2019-11-12
  • 1970-01-01
  • 2013-03-07
  • 2018-02-16
  • 1970-01-01
  • 2016-09-24
  • 2016-03-11
相关资源
最近更新 更多