解决方法
Collations in SQL Server确定匹配和排序字符数据的规则.通常,您将首先根据比较语义和数据使用者所需的排序顺序选择排序规则.
人类通常不会发现binary collations产生他们期望的分类和比较行为.因此,尽管这些提供了最佳性能(特别是纯代码点BIN2版本),但大多数实现都不使用它们.
接下来是原始性能术语(但仅适用于非Unicode字符串)是向后兼容性SQL collations.使用Unicode数据时,这些排序规则使用Windows collation,具有相同的性能特征.这里有一些微妙的陷阱,所以你需要有充分的理由来选择sql排序规则(除非在美国系统上工作,它仍然是默认设置).
由于复杂的Unicode比较和排序规则,Windows排序规则通常是最慢的.尽管如此,这些提供与sql Server中的Windows完全兼容,并定期维护以跟上Unicode标准的变化.对于包含Unicode数据的现代用途,通常建议使用Windows排序规则.
TL; DR
如果你想要的只是区分大小写的比较和排序语义,你应该选择_CS_(用于区分大小写)变体,无论哪个基础排序规则为用户的语言和文化提供预期的行为.例如,这两个都是区分大小写的排序规则:
-- Latin1-General,case-sensitive,accent-sensitive Latin1_General_CS_AS -- Latin1-General,accent-sensitive for Unicode Data,-- sql Server Sort Order 51 on Code Page 1252 for non-Unicode Data sql_Latin1_General_CP1_CS_AS
您可以使用sys.fn_helpcollations查看这些定义
例子
除了整理之外,四个表完全相同;一个二进制文件,一个区分大小写,一个不区分大小写,一个sql区分大小写:
CREATE TABLE #Example_BIN ( string nvarchar(50) COLLATE Latin1_General_BIN NOT NULL ); CREATE TABLE #Example_CS ( string nvarchar(50) COLLATE Latin1_General_CS_AI NOT NULL ); CREATE TABLE #Example_CI ( string nvarchar(50) COLLATE Latin1_General_CI_AI NOT NULL ); CREATE TABLE #Example_sql ( string varchar(50) -- Note varchar COLLATE sql_Latin1_General_CP1_CS_AS NOT NULL );
每个表的相同样本数据:
INSERT #Example_BIN (string) VALUES (N'A'),(N'a'),(N'B'),(N'b'),(N'C'),(N'c'); INSERT #Example_CS SELECT EB.string FROM #Example_BIN AS EB; INSERT #Example_CI SELECT EB.string FROM #Example_BIN AS EB; INSERT #Example_sql SELECT EB.string FROM #Example_BIN AS EB;
现在我们要查找大于’a’的字符串:
SELECT EB.string AS BIN FROM #Example_BIN AS EB WHERE EB.string > N'a' ORDER BY EB.string; SELECT EC.string AS CS FROM #Example_CS AS EC WHERE EC.string > N'a' ORDER BY EC.string; SELECT EC2.string AS CI FROM #Example_CI AS EC2 WHERE EC2.string > N'a' ORDER BY EC2.string; SELECT ES.string AS sql FROM #Example_sql AS ES WHERE ES.string > 'a' -- not Unicode ORDER BY ES.string;
结果:
╔═════╗ ║ BIN ║ ╠═════╣ ║ b ║ ║ c ║ ╚═════╝ ╔════╗ ║ CS ║ ╠════╣ ║ A ║ ║ b ║ ║ B ║ ║ c ║ ║ C ║ ╚════╝ ╔════╗ ║ CI ║ ╠════╣ ║ B ║ ║ b ║ ║ C ║ ║ c ║ ╚════╝ ╔═════╗ ║ sql ║ ╠═════╣ ║ B ║ ║ b ║ ║ C ║ ║ c ║ ╚═════╝
最后…
但请注意,如果我们将Unicode文字与sql排序规则一起使用,则隐式转换规则会导致Windows排序规则比较:
SELECT ES.string AS sql FROM #Example_sql AS ES WHERE ES.string > N'a' ORDER BY ES.string;
…并且sql排序规则结果发生了变化:
╔═════╗ ║ sql ║ ╠═════╣ ║ A ║ ║ B ║ ║ b ║ ║ C ║ ║ c ║ ╚═════╝