由于排序规则不匹配,对两个数据库的查询有错误

Query over two databases has error due to collation mismatch

我是一名 IT 顾问,通常管理硬件和网络,但我们的程序员目前正在休假。我对 MSSQL 查询进行了一些修改,该查询在我们 15 个站点的实践管理软件服务器中的每个服务器上运行两个数据库,但我在一些服务器上遇到了与归类冲突相关的错误。

在我们网站的大多数服务器上它运行良好,但在出现的 15 台服务器中有 4 台出于某种原因使用不同的排序规则。

我研究过尝试更改排序规则,但效果不佳,所以我希望我可以调整查询,以便排序规则的差异对这些服务器来说无关紧要。事实上,如果查询是 'collation agnostic' 会更好,这样我就可以在所有服务器上使用相同的查询而无需关心整理...这可以做到吗?

准确的错误是

Msg 446, Level 16, State 11, Line 1 Cannot resolve collation conflict between "Latin1_General_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in CASE operator for DISTINCT operation.

Msg 446, Level 16, State 11, Line 1 Cannot resolve collation conflict between "Latin1_General_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in CASE operator for DISTINCT operation.

我 运行 的查询是:

SELECT DISTINCT
-- setup columns
[cases].[reference] as MatterNumber,
[dd_entity_d2].[type] as ClientType,
[dd_client].[clientname] as MatterName,
CASE WHEN [dd_entity_d2].[type] ='Individual' THEN etClient.FirstName ELSE [dd_entity_d4].[firstname] END AS FirstName,
CASE WHEN [dd_entity_d2].[type] ='Individual' THEN etClient.LastName   ELSE [dd_entity_d4].[lastname] END AS LastName,
CASE WHEN [dd_entity_d2].[type] ='Individual' THEN [dd_entity_d2].[email]   ELSE [dd_entity_d4].[email] END AS Email,
etActing.[PreferredName] ActingPerson,
[cases].[category] as MatterType,
mt.CreatedOn as MatterOpened,
case mt.[Status]
    when 0 then 'In Progress'
    When 1 then 'On Hold'
    when 2 then 'Completed'
    when 3 then 'Not Proceeding'
else 'Unknown' end as MatterStatus
-- mt.LastUpdatedOn as LastModified,
-- end columns
-- setup data
FROM PracticeEvolve_doc.dbo.[cases]
INNER JOIN PracticeEvolve_c1.dbo.DocumaticsMap dm on dm.DocumaticsID = [cases].ID and dm.Entitytype = 'Matter'
INNER JOIN PracticeEvolve_c1.dbo.[Matter] mt on mt.Matterid = dm.ClickOneID
INNER JOIN PracticeEvolve_c1.dbo.[Client] cl on mt.ClientID = cl.ClientID
INNER JOIN PracticeEvolve_c1.dbo.[Entity] etClient on cl.EntityID = etClient.EntityID
LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emActing on emActing.MatterID = mt.MatterID and emActing.AssociationTypeID = 15
LEFT JOIN PracticeEvolve_c1.dbo.Employee eActing on eActing.EmployeeID = emActing.EmployeeID
LEFT JOIN PracticeEvolve_c1.dbo.Entity etActing on etActing.EntityID = eActing.EntityID
LEFT JOIN PracticeEvolve_doc.dbo.[dd_client] ON [dd_client].[id]=[cases].[clientid]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d2] ON [dd_manytomanydd_entity_d2].[fkid] = [dd_client].[fk_entities]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d2] ON [dd_entity_d2].[id] = [dd_manytomanydd_entity_d2].[pkid]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_party_d3] ON [dd_manytomanydd_party_d3].[fkid] = [dd_entity_d2].[fk_parties]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_party] as [dd_party_d3] ON [dd_party_d3].[id] = [dd_manytomanydd_party_d3].[pkid]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d4] ON [dd_manytomanydd_entity_d4].[fkid] = [dd_party_d3].[fk_entity]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d4] ON [dd_entity_d4].[id] = [dd_manytomanydd_entity_d4].[pkid]
-- end data
-- setup filters
WHERE [cases].[deleted]=0   
    -- AND DATEPART(m, mt.CreatedOn) = DATEPART(m, DATEADD(m, -1, getdate()))
    -- AND DATEPART(yyyy, mt.CreatedOn) = DATEPART(yyyy, DATEADD(m, -1, getdate())) 
    AND mt.CreatedOn >= '2015-07-01'   
    -- AND [dd_entity_d2].[type] = 'Individual'
    -- AND mt.LastUpdatedOn >= '2017-04-02'   
    -- AND mt.[status] = 0
-- end filters 
-- setup sort
ORDER BY Email ASC
-- end sort and query

PracticeEvolve_c1 是 SQL_Latin1_General_CP1_CI_AS 而 PracticeEvolve_doc 是 Latin1_General_CI_AS

我在这里无法理解,如果您能提供任何帮助,我将不胜感激。

干杯 - Reece

编辑: FWIW - 这是我在尝试更改数据库排序规则时遇到的错误:

The object 'MonthToDays365' is dependent on database collation. The database collation cannot be changed if a schema-bound object depends on it. Remove the dependencies on the database collation and then retry the operation

只需修改 CASE 表达式并包含 COLLATE 命令

CASE WHEN [dd_entity_d2].[type] COLLATE SQL_Latin1_General_CP1_CI_AS 
          ='Individual' 
THEN etClient.FirstName COLLATE SQL_Latin1_General_CP1_CI_AS 
ELSE [dd_entity_d4].[firstname] COLLATE SQL_Latin1_General_CP1_CI_AS 
END AS FirstName,