如何修复 SQL Server 查询中的排序规则冲突

问题描述 投票:0回答:5

我正在处理一个视图,其中我在来自两个不同服务器的两个表上使用内部联接。我们正在使用链接服务器。运行查询时我收到此消息:

无法解决等于操作中“SQL_Latin1_General_CP1_CI_AS”和“Arabic_CI_AS”之间的排序规则冲突。

我对整理不太了解。通过互联网搜索我找到了使用

COLLATE
的解决方案,但是
COLLATE
的概念对我来说并不清楚。它会改变任何数据库吗?我正在寻找一种无需对数据库进行任何更改的解决方案。

欢迎任何有关这些概念的好的学习材料。

sql-server database collation
5个回答
99
投票

您可以通过强制查询中使用的排序规则为特定排序规则来解决该问题,例如

SQL_Latin1_General_CP1_CI_AS
DATABASE_DEFAULT
。例如:

SELECT MyColumn
FROM FirstTable a
INNER JOIN SecondTable b
ON a.MyID COLLATE SQL_Latin1_General_CP1_CI_AS = 
b.YourID COLLATE SQL_Latin1_General_CP1_CI_AS

在上面的查询中,a.MyID 和 b.YourID 将是具有基于文本的数据类型的列。使用

COLLATE
将强制查询忽略数据库上的默认排序规则,而是使用提供的排序规则,在本例中为
SQL_Latin1_General_CP1_CI_AS

基本上,每个数据库都有自己的排序规则,“为数据提供排序规则、大小写和重音敏感属性”(来自 http://technet.microsoft.com/en-us/library/ms143726 .aspx) 适用于具有文本数据类型的列,例如

VARCHAR
CHAR
NVARCHAR
等。当两个数据库具有不同的排序规则时,如果不解决两个不同排序规则之间的冲突,则无法使用等于 (=) 等运算符来比较文本列。


9
投票

添加到已接受的答案中,您可以使用

DATABASE_DEFAULT
作为编码。

这允许数据库为您做出选择,并且您的代码变得更加可移植。

SELECT MyColumn
FROM 
    FirstTable a
        INNER JOIN SecondTable b
            ON a.MyID COLLATE DATABASE_DEFAULT = b.YourID COLLATE DATABASE_DEFAULT

4
投票

我通过将查询包装在另一个查询中解决了类似的问题...

初始查询正在工作,查找给出各个输出列,其中一些列来自具有 Max 或 Sum 函数的子查询,其他列来自具有“不同”或大小写替换等的子查询。

我在尝试使用...创建单个输出字段后遇到了排序错误

select
rtrim(field1)+','+rtrim(field2)+','+...

查询会按照我写的那样执行,但是保存sql并重新加载后会出现错误。

最后用类似的东西修复它......

select z.field1+','+z.field2+','+... as OUTPUT_REC
from (select rtrim(field1), rtrim(field2), ... ) z

有些字段是子查询的“max”,如果为 null,则进行大小写替换,其他字段是日期字段,有些字段是左连接(可能为 NULL)...换句话说,混合字段类型。我相信这是由操作系统排序规则和数据库排序规则略有不同引起的问题的原因,但通过在最终选择之前将所有内容转换为修剪字符串,它可以将其排序,所有这些都在 SQL 中。


2
投票

这对我有用:(将 COLLATE 语句添加到 CONCAT 语句中)

SELECT CONCAT(TRIM(A.REFERRED_TO),' - ',TRIM(B.[NAME] COLLATE SQL_Latin1_General_CP1_CS_AS)), COUNT(A.REFERRED_TO) FROM CRIREFS AS A JOIN REFSERVS AS B ON B.CODE = A.REFERRED_TO AND B.ORGUUID = A.ORGUUID


1
投票

我在排序规则方面遇到了问题,因为我的大多数表都带有

Modern_Spanish_CI_AS
,但我从另一个数据库继承或复制的一些表具有
SQL_Latin1_General_CP1_CI_AS
排序规则。

就我而言,解决问题的最简单方法如下:

  1. 我创建了“拉丁美洲”表格的副本,使用脚本表作为...
  2. 新表显然已经获得了我数据库的“现代西班牙语”排序规则
  3. 我已将“拉丁美洲”表的数据复制到新表中,删除旧表并重命名新表。

我希望这对其他用户有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.