SQL Server:设置字符集(不是整理)

时间:2011-10-15 22:35:42

标签: 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;

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

我还设置了排序规则,以证明排序规则是不同的。我询问设置排序规则。 Most questions询问SQL Server中的字符集和编码是通过排序规则来回答的,这与不是相同。

2 个答案:

答案 0 :(得分:14)

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

答案 1 :(得分:7)

扩展@ Martin的回答:

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

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

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

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

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

话虽这么说,要找出正在使用哪个字符集(对于CHARVARCHARTEXT - 即非Unicode - 数据),请运行以下查询,密切关注CodePage字段。 LCID字段指示用于N - 前缀 - 即Unicode - 类型的排序和比较规则的语言环境以及使用Windows排序规则的非Unicode类型 ) :

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转换为更有意义的内容。

关于O.P. {@ 3}} @ Martin的回答:

  

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

虽然微软在选择名称时可能做得更好,但遗憾的是,对于诸如“编码”,“字符集”,“整理”等术语,整个行业都存在一般性的混淆。微软的使用(或“滥用”“整理”只会导致大规模的混乱。但是,如果“utf8”特别是不是一个字符集,那么这个混淆在MySQL中也很明显,因为“utf8”是一个字符集; - )。

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

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

11.1.10.1 Unicode Character Sets

更新2018-10-02

虽然这还不是一个可行的选择,但SQL Server 2019在VARCHAR / CHAR数据类型中引入了对UTF-8的本机支持。目前有太多的bug用于它,但如果它们被修复,那么这是一些场景的一个选项。有关此新功能的详细分析,请参阅我的帖子“Does any DBMS have a collation that is both case-sensitive and accent-insensitive?”。