QFi*_*ast 3 sql-server collation encoding sql-server-2019
我的理解是,比较 Unicode 字符串文字的排序规则是由数据库排序规则决定的。
\n我的数据库正在使用SQL_Latin1_General_CP1_CI_AS
排序规则。
当我将 N\'\xc3\x9f\' 与 \'ss\' 进行比较时,我预计比较会失败。但事实并非如此。我正在尝试找出原因。这是复制品:
\n set nocount on \n go\n use tempdb\n go\n \n SELECT \n @@version as SqlServerVersion,\n CONVERT(nvarchar(128), SERVERPROPERTY(\'collation\')) as SqlServerCollation,\n DB_NAME() AS DatabaseName\n ,DATABASEPROPERTYEX(DB_NAME(), \'Collation\') AS CollationUsedBySQLServerDatabase\n GO\n declare @ss varchar(255) = \'ss\'\n declare @Nscharfess nvarchar(255) = N\'\xc3\x9f\'\n declare @scharfess varchar(255) = \'\xc3\x9f\'\n \n select case when @Nscharfess = @ss then \'Unicode : Strings match\' else \'Unicode : Strings do not match\' end,\n case when @scharfess = @ss then \'SQL_Latin1_General_CP1_CI_AS : Strings match\' else \'SQL_Latin1_General_CP1_CI_AS : Strings do not match\' end\n
Run Code Online (Sandbox Code Playgroud)\n输出:
\n set nocount on \n go\n use tempdb\n go\n \n SELECT \n @@version as SqlServerVersion,\n CONVERT(nvarchar(128), SERVERPROPERTY(\'collation\')) as SqlServerCollation,\n DB_NAME() AS DatabaseName\n ,DATABASEPROPERTYEX(DB_NAME(), \'Collation\') AS CollationUsedBySQLServerDatabase\n GO\n declare @ss varchar(255) = \'ss\'\n declare @Nscharfess nvarchar(255) = N\'\xc3\x9f\'\n declare @scharfess varchar(255) = \'\xc3\x9f\'\n \n select case when @Nscharfess = @ss then \'Unicode : Strings match\' else \'Unicode : Strings do not match\' end,\n case when @scharfess = @ss then \'SQL_Latin1_General_CP1_CI_AS : Strings match\' else \'SQL_Latin1_General_CP1_CI_AS : Strings do not match\' end\n
Run Code Online (Sandbox Code Playgroud)\n我希望 \'\xc3\x9f\' 和 \'ss\' 匹配,但如果我的数据库位于 SQL_Latin1_General_CP1_CI_AS,则不会匹配。我想检查一下我的理解是否存在差距,目前的理解是“对于 Nvarchar() 或 Nchar() 数据类型,SQL Server 从数据库设置中获取排序规则”。这意味着“我的数据库位于 SQL_Latin1_General_CP1_CI_AS,因此比较应该失败。如果成功,SQL Server 使用什么排序规则?为什么?
\n\n\n我的理解是,比较 Unicode 字符串文字的排序规则是由数据库排序规则决定的。
\n
是的,这是正确的。事实上,本地数据库的默认排序规则用于比较 Unicode 和非 Unicode 字符串文字(以及变量/参数)。
\n\n\n当我将 N\'\xc3\x9f\' 与 \'ss\' 进行比较时,我预计比较会失败。但事实并非如此。
\n
两次比较的区别在于,当使用 SQL Server 排序规则(即名称以 开头的排序规则SQL_
)时,非 Unicode 比较不使用 Unicode 比较规则,而如果您使用 Windows 排序规则,它将使用Unicode 和非 Unicode 比较的比较规则相同。
在比较或排序非 Unicode 数据时,SQL Server 排序规则使用一组过时的规则,这些规则比 Unicode 规则的限制要大得多。这些过时的规则不应设定期望(除非您的用例需要旧行为)。
\n这就是为什么首选使用较新的 Windows 排序规则(非常不幸的是,SQL Server仍然使用SQL_Latin1_General_CP1_CI_AS
美国英语语言环境的操作系统上新安装的默认排序规则)。
要查看示例数据的差异,只需将以下内容添加到第二条SELECT
语句中:
,\n case when @scharfess = @ss COLLATE Latin1_General_CI_AS \n then \'Latin1_General_CI_AS : Strings match\'\n else \'Latin1_General_CI_AS : Strings do not match\'\n end;\n
Run Code Online (Sandbox Code Playgroud)\n你会得到回报:
\nLatin1_General_CI_AS : Strings match\n
Run Code Online (Sandbox Code Playgroud)\n即使使用非 Unicode 字符串,过时行为与 Unicode 行为之间的另一个区别可以在以下示例中看到,该示例仅返回一行“2”:
\nLatin1_General_CI_AS : Strings match\n
Run Code Online (Sandbox Code Playgroud)\n