sql-server – 选择可以区分Sql Server中nvarchar列的’ss’和’ß’的二进制排序规则

前端之家收集整理的这篇文章主要介绍了sql-server – 选择可以区分Sql Server中nvarchar列的’ss’和’ß’的二进制排序规则前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
由于sql服务器的默认sql_Latin1_General_CP1_CI_AS排序规则无法区分ss和ß,所以我想根据 here的建议将表中特定列的排序规则更改为sql_Latin1_General_CP437_BIN2.

不过,我不知道这是否是一般的做法.另外我不知道除了以下内容之外的含义:

>更改排序顺序:因为我从来没有对这一列的数据进行排序,对我来说可能不是一个问题.但是,如果你另有想法,请让我知道.
>改变不区分大小写的敏感性:由于我的应用程序总是提供小写的文本,我认为这种改变对我来说也不是一个问题.但是,请让我知道.

我很好奇这个变化的其他主要影响,如果有的话.

此外,我还想知道以下哪一个最适合这种情况:

sql_Latin1_General_CP437_BIN

Description: Latin1-General,binary sort for Unicode Data,sql Server Sort Order 30 on Code Page 437 for non-Unicode Data


sql_Latin1_General_CP437_BIN2

Description: Latin1-General,binary code point comparison sort for Unicode Data,sql Server Sort Order 30 on Code Page 437 for non-Unicode Data


sql_Latin1_General_CP850_BIN

Description: Latin1-General,sql Server Sort Order 40 on Code Page 850 for non-Unicode Data


sql_Latin1_General_CP850_BIN2

Description: Latin1-General,sql Server Sort Order 40 on Code Page 850 for non-Unicode Data

如果您认为还有其他排序规则更适合这种情况,请提及这些.

19.03.2017更新:
对任何人来说这个问题:

>必须检查来自@srutzky和@sqlZim的答案以及相关的引用资源.在这种情况下你不想匆匆忙忙.
>随着更改排序规则不是微不足道:P,保留表数据的备份可能会派上用场.
>还要检查列的依赖关系,如索引和约束;你可能需要删除并创建它们,就像我的情况.

玩的开心 :)

解决方法

关于排序的几点:

>从sql Server 2000开始,sql_ Collat​​ions已被弃用(是的,2000年).如果你可以避免使用它们,你应该(但是并不意味着如果没有紧迫的需要,就改变一堆事情!).

sql_ Collat​​ions的问题实际上仅与VARCHAR(即非Unicode)数据相关,因为NVARCHAR(即Unicode)数据使用来自操作系统的规则.但是,对于VARCHAR数据的排序和比较的规则,不幸的是使用简单的映射,并不包括更复杂的语言规则.这就是为什么ss和ß在使用相同的sql_Latin1_General_CP1_CI_AS排序规则存储为VARCHAR时不等同.这些不推荐的排序方式在单词中间使用时也不能给予较低的重音.非sql_ Collat​​ions(即Windows Collat​​ions)对VARCHAR和NVARCHAR使用相同的规则,因此VARCHAR处理更加强大,与NVARCHAR更一致.
>从sql Server 2005开始,_BIN Collat​​ions已经被弃用了.如果你可以避免使用它们,那么你应该(但是并不意味着如果没有必要的话)改变一堆东西!

_BIN Collat​​ions的问题相当微妙,因为它只影响排序. _BIN和_BIN2之间的比较是相同的,因为它们在字节级别进行比较(因此没有语言规则).但是,由于sql Server(和Windows / PC)是Little Endian,实体按照反向字节顺序存储.当处理双字节“字符”时,这显然是NVARCHAR数据:UTF-16 Little Endian.这意味着Unicode码点U1216在大端系统上具有0x1216的十六进制/二进制表示形式,但在小端系统上存储为0x1612.要完整的圆圈,以便这个最后一点的重要性(希望)变得明显:_BIN Collat​​ions将逐字节(第一个字符之后)进行比较,因此将U1216视为0x16,然后将0x12视为0x12,而_BIN2 Collat​​ions将通过代码点比较代码点,因此将U1216视为0x12,然后将0x16.
>这个特定的列是NVARCHAR(使用sql_Latin1_General_CP1_CI_AS的VARCHAR列不等于ss和ß),因此仅仅这个列,sql_Latin1_General_CP437_BIN2和sql_Latin1_General_CP850_BIN2之间没有区别,因为Unicode是一个单一的全包字符集.
>对于VARCHAR数据,由于它们是不同的代码页(437850),因此这两者都不同于现在使用的代码页(CP1 ==代码1252).
>虽然使用二进制排序通常是过度的,但在这种情况下,可能需要考虑到只有一个区域设置/文化不等于ß与ss:Hungarian.使用匈牙利排序规则可能会有一些您不想要的语言规则(或至少不会期望),所以二进制排序规则似乎是更好的选择(只是你们中没有任何一个要求:-) .请记住,通过使用二进制排序规则,不仅您放弃了所有语言规则,而且您也失去了等同于A(Latin Capital Letter A U+0041)和A(@L_403_5@)相同字符的不同版本的能力.

使用以下查询来查看排序是非二进制的,不等于这些字符:

DECLARE @sql NVARCHAR(MAX) = N'DECLARE @Counter INT = 1;';

SELECT @sql += REPLACE(N'
  IF(N''ß'' COLLATE {Name} = N''ss'' COLLATE {Name})
  BEGIN
    RAISERROR(N''%4d.  {Name}'',10,1,@Counter) WITH NOWAIT;
    SET @Counter += 1;
  END;
',N'{Name}',col.[name]) + NCHAR(13) + NCHAR(10)
FROM   sys.fn_helpcollations() col
WHERE  col.[name] NOT LIKE N'sql[_]%'
AND    col.[name] NOT LIKE N'%[_]BIN%'
ORDER BY col.[name]

--PRINT @sql;
EXEC (@sql);

所以:

>如果要使用二进制排序规则,请使用类似Latin1_General_100_BIN2的内容.
>您不需要更改整个数据库及其所有表的排序规则.这是很多工作,唯一的“内置”机制是无证的(即不支持).
>如果要更改数据库的默认排序规则,这会影响数据库作用域项目(如表,列,索引,函数,存储过程等)的名称解析.意义:您需要退出100%数据库,以及触摸此数据库的所有sql Server代理作业等.
>如果使用此列的大多数/所有查询都需要ß,将ss视为不同的,请继续更改列以使用Latin1_General_100_BIN2.这可能需要删除以下依赖对象,然后在ALTER TABLE之后重新创建:

>索引
>唯一约束
>外键限制

提示:确保检查列的当前NULL / NOT NULL设置,并在ALTER TABLE … ALTER COLUMN …语句中指定它,以便不会更改.>如果只有一些查询需要这个不同的行为,那么在每个条件的基础上(例如WHERE选项卡),只用COLLATE子句覆盖这些比较操作.[ThisColumn] LIKE N’%ss%’COLLATE Latin1_General_100_BIN2). COLLATE关键字只应在运算符的一侧(因为排序规则优先级将应用于另一方)需要.

猜你在找的MsSQL相关文章