【问题标题】:SQL Server: set character set (not collation)SQL Server:设置字符集(不是排序规则)
【发布时间】:2011-12-08 12:40:33
【问题描述】:

在 SQL Server 中创建表时如何设置字段的默认字符集?在 MySQL 中这样做:

CREATE TABLE tableName (
    name VARCHAR(128) CHARACTER SET utf8
) DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

请注意,我在这里设置了两次字符集。这是多余的,我添加了两种方式只是为了演示。

我设置排序规则也是为了证明排序规则是不同的。我询问设置排序规则。 Mostquestions 询问 SQL Server 中的字符集和编码,得到的回答是排序规则,这不是一回事。

【问题讨论】:

  • 它们在 SQL Server 中是一样的。通过在 varchar 列上设置排序规则,您还可以设置代码页。
  • 谢谢马丁。这是在哪里记录的?当然,我浏览了精美的手册(MSDN 在线),但我没有看到任何提及。
  • 排序规则控制 SQL Server 中字符串的物理存储。排序规则指定 [ both ] 表示每个字符的位模式 对字符进行排序和比较的规则。 Link

标签: sql-server character-encoding collation character-set


【解决方案1】:

As stated in BOL

每个 SQL Server 排序规则指定三个属性:

  • 用于 Unicode 数据类型(nchar、nvarchar 和 ntext)的排序顺序。排序顺序定义了字符的顺序 排序,以及在比较操作中评估字符的方式。
  • 用于非 Unicode 字符数据类型(char、varchar 和 text)的排序顺序。
  • 用于存储非 Unicode 字符数据的代码页。

上面的引用来自 2000 个文档。 See also this 2008 link。下面也演示了这一点。

DECLARE @T TABLE 
(
     code TINYINT PRIMARY KEY,
     Arabic_CS_AS CHAR(1) COLLATE Arabic_CS_AS NULL,
     Cyrillic_General_CS_AS CHAR(1) COLLATE Cyrillic_General_CS_AS NULL,
     Latin1_General_CS_AS CHAR(1) COLLATE Latin1_General_CS_AS NULL
);

INSERT INTO @T(code) VALUES (200),(201),(202),(203),(204),(205)

UPDATE @T 
  SET Arabic_CS_AS=CAST(code AS BINARY(1)),
      Cyrillic_General_CS_AS=CAST(code AS BINARY(1)),
      Latin1_General_CS_AS=CAST(code AS BINARY(1))

SELECT * 
FROM @T   

结果

code Arabic_CS_AS Cyrillic_General_CS_AS Latin1_General_CS_AS
---- ------------ ---------------------- --------------------
200  ب            И                      È
201  ة            Й                      É
202  ت            К                      Ê
203  ث            Л                      Ë
204  ج            М                      Ì
205  ح            Н                      Í

【讨论】:

  • 谢谢马丁。不幸的是,他们选择了具有误导性/不完整的术语“排序规则”,它明确指的是排序顺序:collate definition。因此,似乎无法在此设置中使用自定义排序规则(我有一个带有自定义排序规则的不相关 PHP/MySQL 应用程序)。顺便说一句,我喜欢优雅的例子!
  • @dotancohen - 您可以使用显式的 collate 子句来使用不同的比较语义,但您不能定义自己的排序规则。
  • @Martin Smith 您的回答很精彩......所有问题都取决于创建数据库的那一刻......选择正确的排序规则非常重要......
  • @dotancohen 和 Martin:有关字符集和编码的更多详细信息,请参阅我的回答 :-)。 +1 用于显示 3 个代码页/排序规则的变化。
  • @dotancohen 和 Martin:请参阅我答案底部的更新。自 SQL Server 2019 起有新信息。
【解决方案2】:

扩展@Martin 的回答:

如何在 SQL Server 中设置“字符集”取决于您使用的数据类型。如果您正在使用:

  • NVARCHARNCHARNTEXTNTEXT 已弃用,自 SQL Server 2005 起不应使用)都使用 Unicode 字符集,并且无法更改。这些数据类型都被编码为 UTF-16 LE(Little Endian)——一种 16 位编码,每个“字符”为 2 或 4 个字节——这也无法更改。对于这些数据类型,使用的排序规则仅影响区域设置(由排序规则的 LCID 确定),该区域确定用于排序和比较的规则集。

  • XMLN 前缀类型一样,使用 Unicode 字符集并编码为 UTF-16 LE(小尾数),并且两者都不能更改。但与其他字符串数据类型不同,没有与 XML 数据关联的排序规则,因为它无法排序或比较(至少在没有先将其转换为 NVARCHAR(MAX) [preferred] 或 VARCHAR(MAX) 之前不会)。

  • VARCHARCHARTEXTTEXT 已弃用,自 SQL Server 2005 起不应使用)都是 8 位编码,每个“字符”为 1 或 2 个字节.字符集由与每个排序规则关联的代码页确定。排序和比较规则取决于所使用的排序规则的类型:

    • SQL Server 排序规则:这些名称都以SQL_ 开头,自 SQL Server 2000 以来已被弃用,但(不幸的是)今天仍在广泛使用。这些使用简单的规则,在sys.fn_helpcollations() 返回的description 字段中找到“SQL Server 排序顺序”编号。
    • Windows 排序规则:它们的名称​​不SQL_ 开头。这些排序规则允许非 Unicode 字符串数据使用排序规则的 LCID 指示的 Unicode 排序和比较规则。

话虽如此,要找出正在使用的字符集(CHARVARCHARTEXT - 即非 Unicode - 数据),运行以下查询并密切注意 @ 987654347@ 字段。 LCID 字段表示用于N 前缀的区域设置和比较规则 - 即 Unicode - 类型以及使用 Windows 排序规则的非 Unicode 类型if

SELECT *,
       COLLATIONPROPERTY(col.[name], 'CodePage') AS [CodePage],
       COLLATIONPROPERTY(col.[name], 'LCID') AS [LCID]
FROM   sys.fn_helpcollations() col
ORDER BY col.[name];

可以通过 Code Page Identifiers 的 MSDN 页面将代码页 ID 转换为更有意义的内容。


关于@Martin 回答中的 O.P.comment

不幸的是,他们选择了具有误导性/不完整的术语“整理”,该术语明确指的是排序顺序:整理定义。

虽然微软在选择名称时确实可以做得更好,但不幸的是,在“编码”、“字符集”、“排序规则”等术语上,整个行业普遍存在混淆。微软的使用 (或滥用)“整理”只是造成了大规模的混乱。但是,正如这个问题所示,这种混淆在 MySQL 中也很明显,因为“utf8”具体不是字符集;-)。

UTF-8 是 Unicode 字符集的几种编码之一。 UTF-16 和 UTF-32 是另外两种编码。所有这三种编码都表示完全相同的 Unicode 字符集,只是方式不同。查看 MySQL 字符集列表——11.1.10 Supported Character Sets and Collations——“ucs2”、“utf8”、“utf8mb4”、“utf16”、“utf16le”、“utf32”字符集实际上并不是字符集,而是各种表示形式Unicode 字符集。但是,鉴于“字符集”和“编码”概念之间的重叠,很难不产生这种混淆。 11.1.10.1 Unicode Character Sets 页面表明“utf8mb4”、“utf16”、“utf16le”和“utf32”字符集是完整的 Unicode 字符集,而“ucs2”和“utf8”是 Unicode 字符集的子集,特别是第一个65,536 个代码点(又名基本多语言平面 (BMP))。

有关各种 RDBMS 的排序规则的更多信息,请参阅我在 DBA.StackExchange 上对以下问题的回答:

Does any DBMS have a collation that is both case-sensitive and accent-insensitive?


2018 年 10 月 2 日更新

虽然这还不是一个可行的选项,但 SQL Server 2019 在 VARCHAR / CHAR 数据类型中引入了对 UTF-8 的本机支持。目前它有太多的错误无法使用,但如果它们被修复,那么这是一些场景的一个选项。有关此新功能的详细分析,请参阅我的帖子“Native UTF-8 Support in SQL Server 2019: Savior or False Prophet?”。

【讨论】:

  • 我觉得这比最初接受的解释更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 2011-05-05
  • 2017-05-17
  • 2012-08-08
  • 1970-01-01
  • 2020-05-28
  • 2012-07-03
相关资源
最近更新 更多