编码
在大多数情况下,SQL Server 以 UCS-2 / UTF-16 存储 Unicode 数据(即在 XML 和 N 前缀类型中找到的数据)(存储相同,UTF-16 仅处理补充字符正确)。这是不可配置的:没有选项可以使用 UTF-8 或 UTF-32 (请参阅底部的 UPDATE 部分:UTF-8 从SQL Server 2019)。内置函数是否可以正确处理补充字符,以及是否正确排序和比较,取决于使用的排序规则。较旧的排序规则——以SQL_ 开头的名称(例如SQL_Latin1_General_CP1_CI_AS)xor 名称中没有版本号(例如Latin1_General_CI_AS)——将所有补充字符相互等同(由于没有排序重量)。从 SQL Server 2005 开始,他们引入了 90 系列排序规则(名称中带有 _90_ 的排序规则),它至少可以对补充字符进行二进制比较,以便您可以区分它们,即使它们没有排序所需的顺序。这也适用于 SQL Server 2008 中引入的 100 系列排序规则。SQL Server 2012 引入了名称以 _SC 结尾的排序规则,不仅可以正确排序补充字符,而且还允许内置函数按预期解释它们(即将代理对视为单个实体)。从 SQL Server 2017 开始,所有新的排序规则(140 系列)implicitly support Supplementary Characters,因此没有名称以 _SC 结尾的新排序规则。
从 SQL Server 2019 开始,UTF-8 成为支持 CHAR 和 VARCHAR 数据(列、变量和文字)的编码,但不支持 TEXT (请参阅 更新 底部 re: UTF-8 从 SQL Server 2019 开始).
非 Unicode 数据(即在 CHAR、VARCHAR 和 TEXT 类型中找到的数据 - 但不要使用 TEXT,而是使用 VARCHAR(MAX))使用 8 位编码(扩展 ASCII、DBCS 或 EBCDIC)。具体的字符集/编码基于代码页,而代码页又基于列的排序规则,或者是当前数据库对文字和变量的排序规则,或者是实例的排序规则对变量/游标名称和@ 987654347@ 标签,或者在 COLLATE 子句中指定的标签(如果正在使用)。
要查看语言环境如何匹配排序规则,请查看:
要查看与特定排序规则关联的代码页(这是字符集,仅影响 CHAR / VARCHAR / TEXT 数据),请运行以下命令:
SELECT COLLATIONPROPERTY( 'Latin1_General_100_CI_AS' , 'CodePage' ) AS [CodePage];
要查看与特定排序规则关联的 LCID(即区域设置)(这会影响排序和比较规则),请运行以下命令:
SELECT COLLATIONPROPERTY( 'Latin1_General_100_CI_AS' , 'LCID' ) AS [LCID];
要查看可用排序规则的列表及其关联的 LCID 和代码页,请运行:
SELECT [name],
COLLATIONPROPERTY( [name], 'LCID' ) AS [LCID],
COLLATIONPROPERTY( [name], 'CodePage' ) AS [CodePage]
FROM sys.fn_helpcollations()
ORDER BY [name];
默认值
在查看服务器和数据库默认排序规则之前,应该了解这些默认值的相对重要性。
服务器(实际上是实例)默认排序规则用作新创建的数据库(包括系统数据库:master、model、msdb 和 tempdb)的默认值。但这并不意味着任何数据库(4 个系统数据库除外)都在使用该排序规则。可以随时更改数据库默认排序规则(尽管存在可能阻止数据库更改排序规则的依赖项)。但是,服务器默认排序规则并不那么容易更改。有关更改所有排序规则的详细信息,请参阅:Changing the Collation of the Instance, the Databases, and All Columns in All User Databases: What Could Possibly Go Wrong?
服务器/实例归类控件:
- 局部变量名称
-
CURSOR 姓名
-
GOTO 标签
- 实例级元数据
Database默认Collation有三种使用方式:
- 作为新创建的字符串列的默认值。但这并不意味着任何字符串列都在使用该排序规则。列的排序规则可以随时更改。在这里,了解数据库默认值很重要,因为它可以指示最有可能设置的字符串列。
- 作为涉及字符串文字、变量和不接受字符串输入但产生字符串输出的内置函数的操作的排序规则(即
IF (@InputParam = 'something'))。在这里了解数据库默认值绝对重要,因为它控制着这些操作的行为方式。
- 数据库级元数据
列排序规则在CREATE TABLE 或ALTER TABLE {table_name} ALTER COLUMN 时在COLLATE 子句中指定,或者如果未指定,则取自数据库默认值。
由于这里有几个层可以指定排序规则(数据库默认/列/文字和变量),因此生成的排序规则由Collation Precedence 确定。
综上所述,以下查询显示了操作系统、SQL Server 实例和指定数据库的默认/当前设置:
SELECT os_language_version,
---
SERVERPROPERTY('LCID') AS 'Instance-LCID',
SERVERPROPERTY('Collation') AS 'Instance-Collation',
SERVERPROPERTY('ComparisonStyle') AS 'Instance-ComparisonStyle',
SERVERPROPERTY('SqlSortOrder') AS 'Instance-SqlSortOrder',
SERVERPROPERTY('SqlSortOrderName') AS 'Instance-SqlSortOrderName',
SERVERPROPERTY('SqlCharSet') AS 'Instance-SqlCharSet',
SERVERPROPERTY('SqlCharSetName') AS 'Instance-SqlCharSetName',
---
DATABASEPROPERTYEX(N'{database_name}', 'LCID') AS 'Database-LCID',
DATABASEPROPERTYEX(N'{database_name}', 'Collation') AS 'Database-Collation',
DATABASEPROPERTYEX(N'{database_name}', 'ComparisonStyle') AS 'Database-ComparisonStyle',
DATABASEPROPERTYEX(N'{database_name}', 'SQLSortOrder') AS 'Database-SQLSortOrder'
FROM sys.dm_os_windows_info;
安装默认
“默认”的另一种解释可能意味着安装时为 Instance-level 排序规则选择的默认排序规则。这因操作系统语言而异,但使用“美国英语”的系统的(可怕的、可怕的)默认值是SQL_Latin1_General_CP1_CI_AS。在这种情况下,VARCHAR 数据的“默认”编码是 Windows 代码页 1252,NVARCHAR 数据始终是 UTF-16。您可以在此处找到默认 SQL Server 排序规则的操作系统语言列表:Collation and Unicode support: Server-level collations。请记住,这些默认值可以被覆盖;如果在安装期间没有被覆盖,这个列表只是实例将使用的内容。
2018 年 10 月 2 日更新
SQL Server 2019 在 VARCHAR / CHAR 数据类型(不是 TEXT!)中引入了对 UTF-8 的本机支持。这是通过一组新的排序规则完成的,它们的名称都以_UTF8 结尾。这是一个有趣的功能,肯定会帮助一些人,但它有一些“怪癖”,特别是当 UTF-8 没有用于所有列和数据库的默认排序规则时,所以不要不要仅仅因为您听说 UTF-8 神奇地更好而使用它。 UTF-8 完全是为了 ASCII 兼容性而设计的:使仅 ASCII 的系统(即当时的 UNIX)能够在不更改任何现有代码或文件的情况下支持 Unicode。它主要(或仅)使用美国英语字符(和一些标点符号)为数据节省空间是一个副作用。当大部分(或仅)不使用美国英语字符时,数据可能与 UTF-16 大小相同,甚至更大,具体取决于所使用的字符。而且,在节省空间的情况下,性能可能会提高,但也可能会变得更糟。
关于这个新功能的详细分析,请看我的帖子“Native UTF-8 Support in SQL Server 2019: Savior or False Prophet?”。