Query over two databases has error due to collation mismatch

雨燕双飞 提交于 2019-12-11 12:57:15

问题


I'm an IT consultant that usually manages hardware and networks but our programmers are on leave at the moment. I've made some modifications to a MSSQL query that runs over two databases on each of our 15 site's Practice Management Software servers and I'm getting an error on a few of the servers relating to a collation conflict.

On most of our site's servers it runs fine, but there is 4 out the 15 servers that appear two have the databases using different collation for some reason.

I've looked into trying to change the collation, but it didn't go well, so I was hoping maybe I could tweak the query so the difference in collation didn't matter for these servers. In fact, it'd be better if the query was 'collation agnostic' so that I could use the same query across all servers without a care for the collation... Can this be done?

The exact error is

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.

And the query I'm running is:

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 is SQL_Latin1_General_CP1_CI_AS and PracticeEvolve_doc is Latin1_General_CI_AS.

I'm out of my depth here and would greatly appreciate any help you may be able to offer.

Cheers - Reece

EDIT: FWIW - this is the error I got when I tried to change the database collation:

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


回答1:


Just amend the CASE expression and include the COLLATE command

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,


来源:https://stackoverflow.com/questions/48186025/query-over-two-databases-has-error-due-to-collation-mismatch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!