在等于操作中无法解决"SQL_Latin1_General_CP1_CI_AS"和"Latin1_General_CI_AS"之间的排序规则冲突

jho*_*owe 313 sql-server

我有以下代码

SELECT tA.FieldName As [Field Name],
       COALESCE(tO_A.[desc], tO_B.[desc], tO_C.Name, tA.OldVAlue) AS [Old Value],
       COALESCE(tN_A.[desc], tN_B.[desc], tN_C.Name, tA.NewValue) AS [New Value],
       U.UserName AS [User Name],
       CONVERT(varchar, tA.ChangeDate) AS [Change Date] 
  FROM D tA
       JOIN 
       [DRTS].[dbo].[User] U 
         ON tA.UserID = U.UserID
       LEFT JOIN 
       A tO_A 
         on tA.FieldName = 'AID' 
        AND tA.oldValue = CONVERT(VARCHAR, tO_A.ID)
       LEFT JOIN 
       A tN_A 
         on tA.FieldName = 'AID' 
        AND tA.newValue = CONVERT(VARCHAR, tN_A.ID)
       LEFT JOIN 
       B tO_B 
         on tA.FieldName = 'BID' 
        AND tA.oldValue = CONVERT(VARCHAR, tO_B.ID)
       LEFT JOIN 
       B tN_B 
         on tA.FieldName = 'BID' 
        AND tA.newValue = CONVERT(VARCHAR, tN_B.ID)
       LEFT JOIN 
       C tO_C 
         on tA.FieldName = 'CID' 
        AND tA.oldValue = tO_C.Name
       LEFT JOIN 
       C tN_C 
         on tA.FieldName = 'CID' 
        AND tA.newValue = tN_C.Name
 WHERE U.Fullname = @SearchTerm
ORDER BY tA.ChangeDate
Run Code Online (Sandbox Code Playgroud)

在运行代码时,我在为表C添加两个连接后得到了标题中粘贴的错误.我认为这可能与我使用SQL Server 2008的事实有关,并已将此数据库的副本还原到我的机器是2005年.

Val*_*rie 793

我做以下事情:

...WHERE 
    fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT
Run Code Online (Sandbox Code Playgroud)

每次都有效.:)

  • 这是SO上最有用的帖子之一 (59认同)
  • @ppumkin虽然它是一个很好的解决方案,它仍然只是*避免*问题,而不是解决它.除非您想要更改每个查询的排序规则,这是繁琐且无法最佳执行的.虽然这是一个很好的答案,但我认为接受的答案是更好的答案. (6认同)
  • 如果在其他地方(比较,联合,合并等)一起使用相同的两个字段,请确保每个字段都具有指定的排序规则. (4认同)
  • 这非常有用.我正在使用本地数据库并查询链接服务器,他们有两种不同的排序规则.显然我无法更改链接服务器上的排序规则,我不想在本地更改我的排序,所以这绝对是最好的答案. (4认同)
  • 使用此解决方案是因为我正在使用相同的数据库使用两个旧系统,因此我不确定更改表的排序规则是否会破坏功能。 (2认同)

mar*_*c_s 294

您的表中有两个不同的排序规则不匹配.您可以使用以下查询检查表中每列的排序规则:

SELECT
    col.name, col.collation_name
FROM 
    sys.columns col
WHERE
    object_id = OBJECT_ID('YourTableName')
Run Code Online (Sandbox Code Playgroud)

在排序和比较字符串时需要并使用排序规则.在整个数据库中使用单一,唯一的排序规则通常是一个好主意 - 不要在单个表或数据库中使用不同的排序规则 - 您只是在寻找麻烦....

一旦您完成了单个排序规则,您就可以使用此命令更改那些不匹配的表/列:

ALTER TABLE YourTableName
  ALTER COLUMN OffendingColumn
    VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL
Run Code Online (Sandbox Code Playgroud)

更新:要在数据库中查找全文索引,请在此处使用此查询:

SELECT
    fti.object_Id,
    OBJECT_NAME(fti.object_id) 'Fulltext index',
    fti.is_enabled,
    i.name 'Index name',
    OBJECT_NAME(i.object_id) 'Table name'
FROM 
    sys.fulltext_indexes fti
INNER JOIN 
    sys.indexes i ON fti.unique_index_id = i.index_id
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下命令删除全文索引:

DROP FULLTEXT INDEX ON (tablename)
Run Code Online (Sandbox Code Playgroud)

  • 谢谢 OP,我正在设置一个临时表,所以这有帮助,但由于我无法更改表,我需要正确声明它以开始(如下):DECLARE @Table TABLE (CompareMessage VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL) (2认同)

Ray*_*Ray 72

collate在查询中使用该子句:

LEFT JOIN C tO_C on tA.FieldName = 'CID' AND tA.oldValue COLLATE Latin1_General_CI_AS = tO_C.Name  
Run Code Online (Sandbox Code Playgroud)

我可能没有完全正确的语法(检查BOL),但是你可以这样做来为查询动态更改排序规则 - 你可能需要为每个连接添加子句.

编辑:我意识到这是不完全正确- COLLATE子句去您需要更改后场-在这个例子中,我改变了整理的tA.oldValue领域.


Pal*_*ria 27

确定它引发此错误的字段并向其添加以下内容:COLLATE DATABASE_DEFAULT

Code字段上有两个表连接在一起:

...
and table1.Code = table2.Code
...
Run Code Online (Sandbox Code Playgroud)

将您的查询更新为:

...
and table1.Code COLLATE DATABASE_DEFAULT = table2.Code COLLATE DATABASE_DEFAULT
...
Run Code Online (Sandbox Code Playgroud)


Buz*_*zzz 13

当您拥有2个不同的数据库,特别是来自2个不同服务器的2个不同数据库时,很容易发生 最佳选择是将其更改为通用集合并进行连接或比较.

SELECT 
   *
FROM sd
INNER JOIN pd ON sd.SCaseflowID COLLATE Latin1_General_CS_AS = pd.PDebt_code COLLATE Latin1_General_CS_AS
Run Code Online (Sandbox Code Playgroud)


小智 13

@Valkyrie很棒的答案.以为我在这里提出了一个案例,当一个子查询执行相同的内存存储过程时,因为我想知道你的答案在这种情况下是否有效,并且它确实很棒.

...WHERE fieldname COLLATE DATABASE_DEFAULT in (
          SELECT DISTINCT otherfieldname COLLATE DATABASE_DEFAULT
          FROM ...
          WHERE ...
        )
Run Code Online (Sandbox Code Playgroud)


小智 11

在标准添加的地方 collate SQL_Latin1_General_CP1_CI_AS

这适合我.

WHERE U.Fullname = @SearchTerm  collate SQL_Latin1_General_CP1_CI_AS
Run Code Online (Sandbox Code Playgroud)


Rob*_*ert 6

根本原因是您从中获取模式的SQL Server数据库具有与本地安装不同的排序规则.如果您不想担心排序规则,请使用与SQL Server 2008数据库相同的排序规则在本地重新安装SQL Server.


Lar*_*son 6

要在不更改任一数据库的情况下解决查询中的此问题,您可以将表达式转换为“=”符号的另一侧

COLLATE SQL_Latin1_General_CP1_CI_AS
Run Code Online (Sandbox Code Playgroud)

正如这里所建议的。


Who*_*ner 5

检查不匹配的排序规则级别(服务器、数据库、表、列、字符)。

如果是服务器,这些步骤对我有帮助一次:

  1. 停止服务器
  2. 找到您的 sqlservr.exe 工具
  3. 运行这个命令:

    sqlservr -m -T4022 -T3659 -s"name_of_insance" -q "name_of_collation"

  4. 启动你的sql服务器:

    net start name_of_instance

  5. 再次检查服务器的排序规则。

以下是更多信息:

https://www.mssqltips.com/sqlservertip/3519/changing-sql-server-collat​​ion-after-installation/


小智 5

错误(无法解决....之间的排序规则冲突)通常在比较来自多个数据库的数据时发生.

由于您现在无法更改数据库的排序规则,请使用COLLATE DATABASE_DEFAULT.

----------
AND db1.tbl1.fiel1 COLLATE DATABASE_DEFAULT =db2.tbl2.field2 COLLATE DATABASE_DEFAULT 
Run Code Online (Sandbox Code Playgroud)