(以下部分复制了我对相关 DBA.StackExchange 问答的第一部分的回答:为什么不将 SQL_Latin1_General_CI_AS 用于全局系统?并添加了一些附加信息。)
SQL Server 中的排序规则,关于处理各种语言之间的差异(意思是:这不是排序规则所做的所有内容的列表),处理字符串数据的几个方面:
语言环境/ LCID(指文化:en-US、fr-FR 等)
这用于确定对NVARCHAR所有排序规则中的 Unicode /VARCHAR数据以及 Windows(即非SQL_)排序规则的非 Unicode /数据使用的默认语言排序和比较规则的特定于文化的覆盖。
在Unicode整理算法(UCA)定义了如何基于各种规则和选项字符串(各种敏感性,这种情况下,各种第一,其字符是“忽略”,等)进行排序。每个字符都有一个默认排序权重,这称为默认 Unicode 排序规则元素表(DUCET)。但是,不可能在一组规则中捕获所有语言的排序和比较规则,因为字符在具有如何处理相同字符的不同规则的语言之间共享。因此,LCID 指示要应用于默认规则集的覆盖集(如果有)。通用语言环境数据存储库 (CLDR)中描述了这些特定于文化的覆盖。例如:
SELECT CHAR(105) AS [LowerCase], CHAR(73) AS [UpperCase],
UPPER(CHAR(105) COLLATE Turkish_100_CI_AS) AS [TurkishUpperCase];
SELECT 1 WHERE CHAR(105) = CHAR(73) COLLATE Turkish_100_CI_AS;
SELECT 2 WHERE CHAR(105) = CHAR(73) COLLATE Hebrew_100_CI_AS;
SELECT 3 WHERE NCHAR(105) = NCHAR(73) COLLATE Turkish_100_CI_AS;
SELECT 4 WHERE NCHAR(105) = NCHAR(73) COLLATE Hebrew_100_CI_AS;
Run Code Online (Sandbox Code Playgroud)
返回:
LowerCase UpperCase TurkishUpperCase
i I ?
2
4
Run Code Online (Sandbox Code Playgroud)
要查看不同语言如何针对相同比较表现的其他示例,请参阅我的 StackOverflow 答案:nvarchar (Unicode) 列的 COLLATIONS 有何意义?.
对于VARCHAR使用 SQL Server 排序规则的非 Unicode/数据(以 开头的数据SQL_),排序顺序应该是以下 MSDN 页面中描述的内容:附录 D 所选语言的排序顺序。
代码页
这是用于非 Unicode /跨所有排序规则的字符集VARCHAR。需要明确的是,代码页不适用于 Unicode/NVARCHAR数据,因为 Unicode 是单个字符集。并且要非常清楚,Unicode 是一个单一的字符集,不管它是如何编码的:UTF-8、UTF-16 或 UTF-32。
非 Unicode /VARCHAR是 8 位的,但这并不意味着它总是每个字符 1 个字节。Windows 和 SQL Server 支持四种双字节字符集(DBCS),以允许映射超过 256 个字符。与 UTF-8 的工作方式类似,这些双字节字符集是可变长度的,某些字符使用 1 个字节,其他字符使用两个字节。
代码页由 LCID(如上所述)确定,并且是各种二进制排序规则之间唯一有意义的区别(跨所有不推荐使用的_BIN排序规则或单独跨所有_BIN2排序规则;_BIN和BIN2排序规则之间还有另一个区别,但它不是语言-具体的)。这是因为 a) Unicode 是单个字符集,并且 b) 排序基于每个字符的数值,并且不会因语言而异。
代码页之间相同数值的不同字符示例:
检查以下每个网格中的右上角元素:
-- 0xF0 == 240 == ? (in Turkish, Code Page 1254) == ? (in Hebrew, Code Page 1255)
DECLARE @Table TABLE (Turkish VARCHAR(10) COLLATE Turkish_100_CI_AS,
Hebrew VARCHAR(10) COLLATE Hebrew_100_CI_AS);
INSERT INTO @Table (Turkish, Hebrew) VALUES (0xF0, 0xF0);
SELECT * FROM @Table;
Run Code Online (Sandbox Code Playgroud)
返回:
-- 0xF0 == 240 == ? (in Turkish, Code Page 1254) == ? (in Hebrew, Code Page 1255)
DECLARE @Table TABLE (Turkish VARCHAR(10) COLLATE Turkish_100_CI_AS,
Hebrew VARCHAR(10) COLLATE Hebrew_100_CI_AS);
INSERT INTO @Table (Turkish, Hebrew) VALUES (0xF0, 0xF0);
SELECT * FROM @Table;
Run Code Online (Sandbox Code Playgroud)灵敏度
可以在所有排序规则中控制大小写和重音敏感度。假名和宽度敏感度只能在使用 Windows 排序规则时控制,并且在使用SQL_排序规则时假定为“不敏感” 。
此外,所有 Windows 排序规则都应该有一个二元选项(至少是已弃用的_BIN,如果不是也_BIN2),而只有两个SQL_排序规则具有_BIN/_BIN2选项:SQL_Latin1_General_CP850和SQL_Latin1_General_CP437。
此外,仅在使用排序规则时,非 Unicode /VARCHAR数据存在一些行为差异:SQL_
SQL_Latin1_General_CP1_CS_AS)对数据进行排序时,大写字符将排在小写字符之前。a-f在aa使用字符串排序之前进行排序,但在使用单词排序时在它之后)。'æ' = 'ae')。这些扩展基于 Unicode 规则并根据 LCID 而有所不同,如果您在使用VARCHAR数据时需要它们,那么您需要使用 Windows 排序规则(即不以开头SQL_)。但是,NVARCHAR使用任何归类的VARCHAR数据与使用 Windows 归类的数据之间存在行为一致性。
因此,理想情况下,SQL_鉴于上述限制和差异,不应使用排序规则,更不用说它们也已弃用(截至 SQL Server 2014,只有 77 个排序规则和 3810 个 Windows 排序规则)。如果有的话,请尝试使用特定排序规则(例如_100_)的最新版本,如果提供,请使用以_SC.
不幸的是,这SQL_Latin1_General_CP1_CI_AS是在美国安装新实例时的默认设置(至少)。但是人们不应该心甘情愿地SQL_为新的开发选择一种整理,尤其是在需要处理多种文化时。
另请注意:
整理不仅在数据库级别设置,它还在实例级别设置:
实例默认排序规则控制:
master,model,msdb,和tempdb(包括临时表名)COLLATE子句覆盖CREATE TABLE或ALTER TABLE...ADD),除非 a) 通过COLLATE子句覆盖,或 b) 创建临时表时的当前数据库是包含数据库。数据库默认排序规则控制:
CHAR/ VARCHAR/ NCHAR/ NVARCHAR)柱(通过CREATE TABLE或ALTER TABLE...ADD),除非通过重写COLLATE子句。此默认值也适用于表变量,但不适用于从 的默认排序规则中获取默认排序规则的临时表tempdb(除非数据库是包含数据库,在这种情况下,默认值与本地/当前数据库相同)。| 归档时间: |
|
| 查看次数: |
1554 次 |
| 最近记录: |