Sql server SQL Server:设置字符集(非排序规则)

Sql server SQL Server:设置字符集(非排序规则),sql-server,character-encoding,collation,character-set,Sql Server,Character Encoding,Collation,Character Set,在SQL Server中创建表时,如何设置字段的默认字符集?在MySQL中,可以这样做: CREATE TABLE tableName ( name VARCHAR(128) CHARACTER SET utf8 ) DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; 注意,我在这里设置了两次字符集。这是多余的,我添加这两种方法只是为了演示 我设置排序规则也是为了证明排序规则是不同的。我不是在问设置排序规则。询问SQL

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

CREATE TABLE tableName (
    name VARCHAR(128) CHARACTER SET utf8
) DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
注意,我在这里设置了两次字符集。这是多余的,我添加这两种方法只是为了演示

我设置排序规则也是为了证明排序规则是不同的。我不是在问设置排序规则。询问SQL Server中的字符集和编码时,答案是排序规则,而排序规则与此不同。

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

  • 用于Unicode数据类型(nchar、nvarchar和ntext)的排序顺序。排序顺序定义了字符的排序顺序 排序,以及在比较操作中计算字符的方式
  • 用于非Unicode字符数据类型(char、varchar和text)的排序顺序
  • 用于存储非Unicode字符数据的代码页
以上报价来自2000份文件。下面的例子也说明了这一点

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  ح            Н                      Í

要扩展@Martin的答案:

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

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

  • XML
    ,与
    N
    前缀类型一样,使用Unicode字符集,编码为UTF-16 LE(小端),并且这两种类型都不能更改。但与其他字符串数据类型不同,没有与
    XML
    数据相关联的排序规则,因为无法对其进行排序或比较(至少必须先将其转换为
    NVARCHAR(MAX)
    [首选]或
    VARCHAR(MAX)

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

    • SQL Server排序规则:这些排序规则的名称都以
      SQL\uu
      开头,并且自SQL Server 2000以来已被弃用,但(不幸的是)至今仍在广泛使用。它们使用简单的规则,表示为“SQL Server排序顺序”编号,如
      sys.fn\u helpcollations()
      返回的
      description
      字段中所示
    • Windows排序规则:这些排序规则的名称都不是以
      SQL\uu
      开头。这些排序规则允许非Unicode字符串数据使用由排序规则的LCID指示的Unicode排序和比较规则
也就是说,要找出正在使用的字符集(对于
CHAR
VARCHAR
TEXT
——即非Unicode数据),请运行以下查询并密切注意
CodePage
字段。
LCID
字段指示用于排序和比较带前缀的
N
类型(即Unicode)以及非Unicode类型(如果使用Windows排序规则)的区域设置:

SELECT *,
       COLLATIONPROPERTY(col.[name], 'CodePage') AS [CodePage],
       COLLATIONPROPERTY(col.[name], 'LCID') AS [LCID]
FROM   sys.fn_helpcollations() col
ORDER BY col.[name];
代码页ID可以通过的MSDN页面转换为更有意义的内容


关于O.p.关于@Martin的回答:

不幸的是,他们选择了误导性/不完整的术语“排序规则”,该术语清楚地指排序顺序:collate定义

诚然,微软在选择一个名称时本可以做得更好,但不幸的是,在诸如“编码”、“字符集”、“排序规则”等术语上存在着普遍的、行业范围的混淆。微软对“排序规则”的使用(或误用)只会导致大量混淆。但是,正如这个问题所示,这种混淆在MySQL中也很明显,因为“utf8”并不是一个字符集;-)

UTF-8是Unicode字符集的几种编码之一。UTF-16和UTF-32是另外两种编码。这三种编码都表示完全相同的Unicode字符集,只是方式不同。查看MySQL字符集列表-“ucs2”、“utf8”、“utf8mb4”、“utf16”、“utf16le”、“utf32”字符集本身实际上不是字符集,而是Unicode字符集的各种表示形式。但是,鉴于“字符集”和“编码”概念之间的重叠,很难避免这种混淆。页面指出“utf8mb4”、“utf16”、“utf16le”和“utf32”字符集是完整的Unicode字符集,“ucs2”和“utf8”是Unicode字符集的子集,特别是前65536个代码点(也称为基本多语言平面(BMP))

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


更新2018-10-02


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

它们在SQL Server中是相同的。通过设置
varchar
列的排序规则,您还可以设置代码页。谢谢Martin。记录在哪里?我当然通过了罚款