dot*_*hen 13 sql-server collation character-encoding character-set
在SQL Server中创建表时如何设置字段的默认字符集?在MySQL中,我们这样做:
CREATE TABLE tableName (
name VARCHAR(128) CHARACTER SET utf8
) DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
Run Code Online (Sandbox Code Playgroud)
请注意,我在这里设置了两次字符集.这是多余的,我添加了两种方式来演示.
我还设置了排序规则,以证明排序规则是不同的.我不是要求设置整理.大多数 关于SQL Server中的字符集和编码的问题都通过整理来回答,这不是一回事.
Mar*_*ith 15
每个SQL Server排序规则指定三个属性:
- 用于Unicode数据类型(nchar,nvarchar和ntext)的排序顺序.排序顺序定义字符的排序顺序,以及在比较操作中计算字符的方式.
- 用于非Unicode字符数据类型(char,varchar和text)的排序顺序.
- 用于存储非Unicode字符数据的代码页.
以上引用来自2000个文档.另见2008年的链接.以下也证明了这一点.
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
Run Code Online (Sandbox Code Playgroud)
结果
code Arabic_CS_AS Cyrillic_General_CS_AS Latin1_General_CS_AS
---- ------------ ---------------------- --------------------
200 ? ? È
201 ? ? É
202 ? ? Ê
203 ? ? Ë
204 ? ? Ì
205 ? ? Í
Run Code Online (Sandbox Code Playgroud)
扩展@ Martin的答案:
如何在SQL Server中设置"字符集"取决于您使用的数据类型.如果您正在使用:
NVARCHAR
,NCHAR
和NTEXT
(NTEXT
已弃用,不应在SQL Server 2005中使用)都使用Unicode字符集,但无法更改.这些数据类型都编码为UTF-16 LE(Little Endian) - 一个16位编码,每个"字符"为2或4个字节 - 这也无法更改.对于这些数据类型,正在使用的排序规则仅影响区域设置(由排序规则的LCID确定),该区域设置确定用于排序和比较的规则集.
XML
与N
-prefixed类型一样,使用Unicode字符集并编码为UTF-16 LE(Little Endian),并且这些都不能更改.但与其他字符串数据类型不同,没有与XML
数据关联的排序规则,因为无法对其进行排序或比较(至少在没有首先将其转换为NVARCHAR(MAX)
[preferred]或VARCHAR(MAX)
)时也是如此.
VARCHAR
,CHAR
和TEXT
(TEXT
已弃用,不应在SQL Server 2005中使用)都是8位编码,每个"字符"为1或2个字节.字符集由与每个排序规则关联的代码页确定.排序和比较规则取决于所使用的排序规则的类型:
SQL_
从SQL Server 2000 开始,这些名称都以名称开头并且已被弃用,但(不幸的是)现在仍然广泛使用.这些使用简单的规则表示为"SQL Server排序顺序"编号,该编号在description
返回的字段中找到sys.fn_helpcollations()
.SQL_
.这些排序规则允许非Unicode字符串数据使用排序规则的LCID指示的Unicode排序和比较规则.话虽这么说,要找出正在使用哪个字符集(for CHAR
,VARCHAR
和TEXT
- 即非Unicode - 数据),请运行以下查询并密切关注该CodePage
字段.该LCID
字段指示用于排序的区域设置和N
- 如果使用Windows排序规则的Unicode类型以及非Unicode类型的排序和比较规则:
SELECT *,
COLLATIONPROPERTY(col.[name], 'CodePage') AS [CodePage],
COLLATIONPROPERTY(col.[name], 'LCID') AS [LCID]
FROM sys.fn_helpcollations() col
ORDER BY col.[name];
Run Code Online (Sandbox Code Playgroud)
可以通过代码页标识符的MSDN页面将代码页ID转换为更有意义的内容.
关于OP 对@ Martin答案的评论:
不幸的是,他们选择了误导性/不完整的术语"整理",明确指的是排序顺序:整理定义.
虽然微软在选择名称时可能做得更好,但不幸的是,对于诸如"编码","字符集","整理"等术语,整个行业都存在一般性的混淆.微软使用(或滥用) "整理"只是造成了大规模的混乱.但是,在这个问题中所显示的混乱也很明显,因为"utf8"特别不是字符集;-).
UTF-8是Unicode字符集的几种编码之一.UTF-16和UTF-32是另外两种编码.所有这三种编码都以不同的方式表示完全相同的Unicode字符集.查看MySQL字符集列表 - 11.1.10支持的字符集和排序规则 - "ucs2","utf8","utf8mb4","utf16","utf16le","utf32"字符集实际上不是字符集,每个se,但Unicode字符集的各种表示.但是,鉴于"字符集"和"编码"概念之间的重叠,很难不会产生这种混淆.该11.1.10.1 Unicode字符集页指出,"utf8mb4","UTF-16","utf16le应按"和"UTF32"的字符集是完整的Unicode字符集,而"UCS2"和"UTF-8"是Unicode字符集的子集,特别是前65,536个代码点(又名Basic Multilingual Plane(BMP)).
有关各种RDBMS的排序规则的更多信息,请参阅我对DBA.StackExchange上的以下问题的回答:
更新2018-10-02
虽然这还不是一个可行的选择,但SQL Server 2019在VARCHAR
/ CHAR
datatypes中引入了UTF-8的原生支持.目前有太多的bug用于它,但如果它们被修复,那么这是一些场景的选项.请参阅我的帖子," SQL Server 2019中的原生UTF-8支持:救世主还是假先知? ",详细分析了这一新功能.