Issue in procedure (resolve the collation conflict) - sql-server

I have written a stored procedure like below lines of code
ALTER PROCEDURE [dbo].[pr_AgentLinceseInfo_Fetch]
AS
BEGIN
IF OBJECT_ID('tempdb..#BrList') IS NOT NULL
DROP TABLE #BrList
CREATE TABLE #BrList
(
AgentCode nvarchar(max)
,BrokerName nvarchar(max)
,LicenceID bigint
,LicenceNumber nvarchar(max)
,EffectiveDate datetime
,ExpirationDate datetime
,State nvarchar(max)
);
INSERT INTO #BrList
SELECT
a.AgentCode AS BrokerCode,
sy.BrokerName,
L.Licence, L.LicenceNumber,
DateIssued AS EffectiveDate,
L.ExpirationDate,
J.JurisdictionX AS State
FROM
tbAgent AS a
INNER JOIN
tbLicence L ON L.AgentId = a.Agent
LEFT OUTER JOIN
(SELECT Jurisdiction, JurisdictionX
FROM tbJurisdiction) AS j ON j.Jurisdiction =
(CASE
WHEN ISNULL(L.Jurisdiction, '0') = '0'
THEN a.PhysicalAddressState
ELSE L.Jurisdiction
END)
LEFT OUTER JOIN
(SELECT
SystemUser, (FirstName + ' ' + LastName) AS BrokerName
FROM tbSystemUser) AS sy ON sy.SystemUser = a.SystemUser
SELECT * FROM #BrList
SELECT
t.*, p.ProductX, p.ProductCode
FROM
tbCompanyAgent ca
LEFT OUTER JOIN
(SELECT
AgentCode, BrokerName,
LicenceID, LicenceNumber,
EffectiveDate, ExpirationDate, [State]
FROM #BrList) AS t ON t.LicenceNumber = ca.LicenceNumber
INNER JOIN
tbProduct p ON p.Product = ca.ProductId
DROP TABLE #BrList
END
When we execute this procedure, it throws error message
Cannot resolve the collation conflict
Cannot resolve the collation
conflict between "SQL_Latin1_General_CP1_CI_AS" and
"Latin1_General_CI_AI" in the equal to operation.

The problem is you have two different collations in comparing columns
You should not have two different collation in columns when you want to compare them.
Example:
Consider the following query
SELECT 1
WHERE 'a' COLLATE SQL_Latin1_General_CP1_CI_AS = 'a' COLLATE Latin1_General_CI_AI
Which will throw error stating
Msg 468, Level 16, State 9, Line 1 Cannot resolve the collation
conflict between "Latin1_General_CI_AI" and
"SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
It can resolved by explictly making the collation same in both LHS and RHS
SELECT 1
WHERE 'a' COLLATE SQL_Latin1_General_CP1_CI_AS = 'a' COLLATE SQL_Latin1_General_CP1_CI_AS.
Try updating your query like this
SELECT t.*,
p.ProductX,
p.ProductCode
FROM tbCompanyAgent ca
LEFT OUTER JOIN (SELECT AgentCode,
BrokerName,
LicenceID,
LicenceNumber,
EffectiveDate,
ExpirationDate,
[State]
FROM #BrList) AS t
ON t.LicenceNumber COLLATE SQL_Latin1_General_CP1_CI_AS = ca.LicenceNumber COLLATE SQL_Latin1_General_CP1_CI_AS
INNER JOIN tbProduct p
ON p.Product COLLATE SQL_Latin1_General_CP1_CI_AS = ca.ProductId COLLATE SQL_Latin1_General_CP1_CI_AS

jUST ADD this line -> SQL_Latin1_Generstrong textal_CP1_CI_AS in your joinings. Thats it :)
https://premkt.blogspot.my/2016/12/error-cannot-resolve-collation-conflict.html

Related

T-SQL Merge from multiple source records

I've seen several similar questions but haven't found one that answers my question.
I have a source table with many individual notes for a company
CompanyName, Notes3
Company1, "spoke with someone"
Company2, "Email no longer works"
Company1, "Moved address"
I have a destination table (vchCompanyName is unique here)
vchCompanyName, vchNotes
Company1, "started business in 2005"
Company2, null
I want to end up with
vchCompanyName, vchNotes
Company1, "started business in 2005
spoke with someone
Moved address"
Company2, "Email no longer works"
I have tried this code
WITH CTE
AS (SELECT ROW_NUMBER() OVER (PARTITION BY CompanyName, Notes3 ORDER BY CompanyName) RowNum, *
FROM CompanyContact
)
merge dCompany as target
using CTE as source
on target.vchcompanyname = source.companyname
when matched and len(source.notes3)>0 and source.RowNum = 1
then
update set target.vchnote = vchnote + CHAR(13) + source.Notes3
But get the error
The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.
Which is accurate.
I have also tried STRING_AGG but get an undefined UDF error.
How do I change my code to run iteratively?
--EDIT--
I had tried the following update code
WITH CTE
AS (SELECT ROW_NUMBER() OVER (PARTITION BY CompanyName, Notes3 ORDER BY CompanyName) RowNum, *
FROM CompanyContact
)
UPDATE dCompany SET vchNote = vchNote +
(select CHAR(13) + cc.Notes3 from CompanyContact cc
inner JOIN dCompany dc ON dc.vchCompanyName COLLATE database_default = LEFT(cc.CompanyName,50) COLLATE database_default
inner join CTE on dc.vchCompanyName COLLATE database_default = LEFT(CTE.CompanyName,50) COLLATE database_default
WHERE LEN(cc.Notes3)>0
and RowNum = 1
);
But get the error
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
#Chris Crawshaw, I will approach this by doing a 'union all' on the source and destination table to pick up all the notes for each company. Then using the STUFF function, it is easy to concatenate all the notes into one cell, while grouping by the induvidual company names. See the mockup below:
DECLARE #Source TABLE (CompanyName VARCHAR(20), Notes3 VARCHAR(50))
INSERT INTO #Source
SELECT 'Company1', 'spoke with someone' UNION ALL
SELECT 'Company2', 'Email no longer works' UNION ALL
SELECT 'Company1', 'Moved address'
DECLARE #Destination TABLE (vchCompanyName VARCHAR(20), vchNotes VARCHAR(500))
INSERT INTO #Destination
SELECT 'Company1', 'started business in 2005' UNION ALL
SELECT 'Company2', NULL
;WITH Temp AS (
SELECT *
FROM
(
SELECT *
FROM
#Destination D
WHERE D.vchNotes is not null
UNION ALL
SELECT *
FROM
#Source S
)h
)
update D
SET D.vchNotes=U.vchNotes
FROM #Destination D
LEFT JOIN(
SELECT t2.vchCompanyName, vchNotes=STUFF((
SELECT ',' + vchNotes
FROM Temp t1 where t1.vchCompanyName=t2.vchCompanyName
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM
#Destination t2
GROUP BY
t2.vchCompanyName
)U ON
U.vchCompanyName=D.vchCompanyName
--TEST--
SELECT *
FROM
#Destination

How to update uniqueidentifier (GUID) from nvarchar in SQL Server (GUID with no dashes)

Cannot update uniqueidentifier field without dashes
update a
set GUID = replace(b.guid,'-','')
from table1 a
join table2 b on a.ID=b.ID
I get this error:
Msg 8169, Level 16, State 2, Line 26
Conversion failed when converting from a character string to uniqueidentifier.
The GUID in table1 must be in "no dashes format"
e1336903e4d04d2a88ad23ed87ddfff0
The GUID in tabl2 is
E1336903-E4D0-4D2A-88AD-23ED87DDFFF0
I have tried casting to varchar(36) and other variations same error
Thank you!
Try below code and create [Guid] With data type NVarchar(36)
IF OBJECT_ID(N'tempdb..##Temp1') IS NOT NULL
DROP TABLE ##Temp1
CREATE TABLE ##Temp1 (
Id INT identity
,Gid NVARCHAR(36)
)
INSERT INTO ##Temp1 (Gid)
SELECT NEWID()
IF EXISTS (
SELECT 1
FROM ##Temp1
WHERE CHARINDEX('-', Gid) > 0
)
BEGIN
UPDATE T2
SET Gid = REPLACE(T3.Gid, '-', '')
FROM ##Temp1 t2
INNER JOIN ##Temp1 AS T3 ON T3.Id = t2.Id
END
ELSE
BEGIN
PRINT 'No record contains with symbol ''-'''
END
SELECT * FROM ##Temp1

Collation issue while join query in MVC5 and SQL Server 2012

When I join two tables I got a collation issue that is
System.Data.SqlClient.SqlException: Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AI" in the equal to operation.
Then I set the collation in my db using the following code
ALTER DATABASE [CAM] COLLATE SQL_Latin1_General_CP1_CI_AS;
ALTER TABLE CAM_Users
ALTER COLUMN [EmployeeCode] VARCHAR(50)
COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL;
But I still get the same error.
My join query is this:
List<DTOUserManagement> users = (from CAMuser in _unitOfWorkAsync.RepositoryAsync<CAM_Users>().Queryable()
join QRuser in _unitOfWorkAsync.RepositoryAsync<CAM_V_EmployeeMaster>().Queryable() on CAMuser.EmployeeCode equals QRuser.EmployeeCode into t
from t1 in t.DefaultIfEmpty()
join CAMDomain in _unitOfWorkAsync.RepositoryAsync<CAM_Domain>().Queryable() on CAMuser.DomainID equals CAMDomain.DomainID into t2
from t3 in t2.DefaultIfEmpty()
where CAMuser.IsActive
select new DTOUserManagement
{
TransactUserCode = CAMuser.TransactUserCode,
EmployeeCode = CAMuser.EmployeeCode,
EmployeeName = t1.EmployeeName,
Email = t1.EMail,
DomainID = CAMuser.DomainID,
DomainName = t3.DomainName,
IsActive = CAMuser.IsActive,
AssignedRole = CAMuser.AssignedRoles
}).ToList();
How can I solve this?
Please reply anybody
The problem here is that the COLLATION must match on joining columns.
There are two ways to fix this. First you could change the collation on each column. Or second, you can change the collation at execution time. Here's an example of the second approach:
Sample Data
/* T1 and T2 are identical tables in structre and content, except
* for the collation.
*/
DECLARE #T1 TABLE
(
ID VARCHAR(3) COLLATE SQL_Latin1_General_CP1_CI_AS
)
;
DECLARE #T2 TABLE
(
ID VARCHAR(3) COLLATE Latin1_General_CI_AI
)
;
INSERT INTO #T1
(
ID
)
VALUES
('x'),
('y'),
('z')
;
INSERT INTO #T2
(
ID
)
VALUES
('x'),
('y'),
('z')
;
Anti Pattern - Will not Work
/* This query will failed with the error:
* Cannot resolve the collation conflict between "Latin1_General_CI_AI" and "SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
*/
SELECT
*
FROM
#T1 AS t1
INNER JOIN #T2 AS t2 ON t1.ID = t2.ID
;
Corrected - No Error
/* Success.
*/
SELECT
*
FROM
#T1 AS t1
INNER JOIN #T2 AS t2 ON t1.ID = t2.ID COLLATE Latin1_General_CI_AI
;
You need to check your tables that are involved in these JOINs here to verify that all columns involved have the same collation.
You can do this with this SQL query:
SELECT
TableName = t.Name,
ColumnName = c.name,
Collation = c.collation_name
FROM
sys.columns c
INNER JOIN
sys.tables t ON t.object_id = c.object_id
INNER JOIN
sys.types ty ON c.system_type_id = ty.system_type_id
WHERE
t.name IN ('CAM_Users', 'CAM_Domain') -- add any further tables to check
AND ty.name IN ('char', 'nchar', 'nvarchar', 'varchar')
ORDER BY
t.name, c.name
If there are columns that do not match the database default collation, you need to change those to be the same as all other columns. Once all the string columns in those tables are the same collation, then your joins should work.
Update: use this query to find those tables & columns that do not have the current default database collation:
SELECT
TableName = t.Name,
ColumnName = c.name,
Collation = c.collation_name
FROM
sys.columns c
INNER JOIN
sys.tables t ON t.object_id = c.object_id
INNER JOIN
sys.types ty ON c.system_type_id = ty.system_type_id
WHERE
ty.name IN ('char', 'nchar', 'nvarchar', 'varchar')
AND c.collation_name <> 'SQL_Latin1_General_CP1_CI_AS'
ORDER BY
t.name, c.name

Sql Server error [SQLState 42000] (Error 325)

I have a script that utilizes the new Merge Output clause. I've run it in 3 different instances (all non-Production environments) and it works great. When I tried running it in our production environment, I get the error:
Executed as user: xxx\xxx. Incorrect syntax near 'Merge'. You
may need to set the compatibility level of the current database to a
higher value to enable this feature. See help for the SET
COMPATIBILITY_LEVEL option of ALTER DATABASE. [SQLSTATE 42000] (Error
325) Incorrect syntax near 'Merge'. You may need to set the
compatibility level of the current database to a higher value to
enable this feature. See help for the SET COMPATIBILITY_LEVEL option
of ALTER DATABASE. [SQLSTATE 42000] (Error 325). The step failed.
I've checked the versions of each instance and they are all 10.0.4000.0. All of the non-system databases are set to compatibility level 90 (2005), and system databases are set to 100 (2008). What else do I need to check to see where my production instance is different from the other non-Production instances?
Here's the query:
Declare #user varchar(20),
#message varchar(max)
Set #user = 'ISS20120917-144'
Create Table #data
(
CustomerEventID_Surrogate Int Identity (1,1) Not Null Primary Key,
CustomerNumber Int Not Null,
ConvictionEventID Int Not Null,
CustomerEventHierarchyID Int Not Null,
SanctionEventID Int Not Null,
ReferenceNumber varchar(40) Null,
ConvictionACDID Int Null,
State_Code varchar(2) Not Null,
County_ID Int Null,
CitationCDLHolderValueID Int Null,
Hazmat Bit Null,
CMV Bit Null,
PassengerEndorsement Bit Null,
OccurrenceDate DateTime Not Null,
ConvictionDate DateTime Not Null,
CourtOrder Bit Null
)
Create Table #surrogatemap
(
CustomerEventID_Surrogate Int Not Null,
NewCustomerEventID Int Not Null
)
Create Table #surrogateHIDmap
(
NewCustomerEventID Int Not Null,
NewHistoryEventDetailID Int Not Null
)
Begin Tran
Begin Try
Insert Into #data
Select ce.Cust_No,
ce.CustomerEventID,
ceh.CustomerEventHierarchyID,
ceSAN.CustomerEventID,
ce.ReferenceNumber,
hed.ACDID,
hed.State_Code,
hed.County_ID,
hed.CitationCDLHolderValueID,
hed.Hazmat,
hed.CMV,
hed.PassengerEndorsement,
hed.OccurrenceDate,
Case When cd.ConvictionDate IS NOT NULL Then cd.ConvictionDate
Else hed.OccurrenceDate
End As [ConvictionDate],
hed.CourtOrder
From IADS..CustomerEvent ce
Inner Join IADS..HistoryEventDetail hed On hed.CustomerEventID = ce.CustomerEventID
And hed.EndDate IS NULL
Inner Join IADS..CustomerEventCode cec On cec.CustomerEventCodeID = hed.CustomerEventCodeID
And cec.CustomerEventCodeID <> -51
Left Outer Join IADS..ConvictionDetail cd On cd.HistoryEventDetailID = hed.HistoryEventDetailID
Inner Join IADS..CustomerEventHierarchy ceh On ceh.CustomerEventID = ce.CustomerEventID
And ceh.EndDate IS NULL
Inner Join IADS..CustomerEvent ceSAN On ceSAN.CustomerEventID = ceh.RelatedCustomerEventID
And ceSAN.CustomerEventDispositionID IS NULL
Inner Join IADS..CustomerSanctionDetail csd On csd.CustomerEventID = ceSAN.CustomerEventID
And csd.SanctionDiscardedReasonID IS NULL
Inner Join IADS..SanctionReasonCode src On src.SanctionReasonCodeID = csd.SanctionReasonCodeID
And src.SanctionReasonCodeID = -320
Where ce.CustomerEventDispositionID IS NULL
Merge Into IADS..CustomerEvent
Using #data As src On 1 = 0
When Not Matched Then
Insert
(
CustomerEventCategoryID,
Cust_No,
ReferenceNumber,
CreatedBy,
CreatedDate,
UpdatedBy,
UpdatedDate
)
Values
(
-2,
src.CustomerNumber,
src.ReferenceNumber,
#user,
GetDate(),
#user,
GetDate()
)
Output
src.CustomerEventID_Surrogate,
inserted.CustomerEventID
Into #surrogatemap;
Select sm.NewCustomerEventID,
-8 As [HistoryEventTypeID],
-51 As [CustomerEventCodeID],
131 As [ACDID],
d.State_Code,
d.County_ID,
d.CitationCDLHolderValueID,
d.OccurrenceDate,
d.ConvictionDate,
d.Hazmat,
d.CMV,
d.CourtOrder,
GETDATE() As [EffectiveDate],
#user As [UpdatedBy],
GETDATE() As [UpdatedDate],
d.ConvictionACDID,
d.PassengerEndorsement
Into #hiddata
From #data d
Inner Join #surrogatemap sm On sm.CustomerEventID_Surrogate = d.CustomerEventID_Surrogate
Merge Into IADS..HistoryEventDetail
Using #hiddata As src On 1 = 0
When Not Matched Then
Insert
(
CustomerEventID,
HistoryEventTypeID,
CustomerEventCodeID,
ACDID,
State_Code,
County_ID,
CitationCDLHolderValueID,
OccurrenceDate,
Hazmat,
CMV,
CourtOrder,
EffectiveDate,
UpdatedBy,
UpdatedDate,
UnderlyingACDID,
PassengerEndorsement
)
Values
(
src.NewCustomerEventID,
src.HistoryEventTypeID,
src.CustomerEventCodeID,
src.ACDID,
src.State_Code,
src.County_ID,
src.CitationCDLHolderValueID,
src.OccurrenceDate,
src.Hazmat,
src.CMV,
src.CourtOrder,
src.EffectiveDate,
src.UpdatedBy,
src.UpdatedDate,
src.ConvictionACDID,
src.PassengerEndorsement
)
Output
src.NewCustomerEventID,
inserted.HistoryEventDetailID
Into #surrogateHIDmap;
Insert Into IADS..CustomerEventHierarchy
(
CustomerEventID,
RelatedCustomerEventID,
EffectiveDate,
UpdatedBy,
UpdatedDate
)
Select sm.NewCustomerEventID,
d.SanctionEventID,
GETDATE(),
#user,
GETDATE()
From #data d
Inner Join #surrogatemap sm On sm.CustomerEventID_Surrogate = d.CustomerEventID_Surrogate
Insert Into IADS..CourtFineDetail
(
HistoryEventDetailID,
ConvictionDate
)
Select s.NewHistoryEventDetailID,
d.ConvictionDate
From #hiddata d
Inner Join #surrogateHIDmap s On s.NewCustomerEventID = d.NewCustomerEventID
-- Remove the tie to the SUS077
Update IADS..CustomerEventHierarchy
Set EndDate = GETDATE(),
UpdatedBy = #user,
UpdatedDate = GETDATE()
Where CustomerEventHierarchyID In (Select CustomerEventHierarchyID From #data)
-- Build temp table containing the records that have already purged
Select ce.Cust_No,
ce.CustomerEventID,
ceh.CustomerEventHierarchyID
Into #disposedRecords
From IADS..CustomerEvent ce
Inner Join IADS..HistoryEventDetail hed On hed.CustomerEventID = ce.CustomerEventID
And hed.EndDate IS NULL
Inner Join IADS..CustomerEventCode cec On cec.CustomerEventCodeID = hed.CustomerEventCodeID
And hed.CustomerEventCodeID <> -51
Inner Join IADS..CustomerEventHierarchy ceh On ceh.CustomerEventID = ce.CustomerEventID
And ceh.EndDate IS NULL
Inner Join IADS..CustomerEvent ceSAN On ceSAN.CustomerEventID = ceh.RelatedCustomerEventID
And ceSAN.CustomerEventDispositionID IS NOT NULL
Inner Join IADS..CustomerSanctionDetail csd On csd.CustomerEventID = ceSAN.CustomerEventID
And csd.SanctionReasonCodeID = -320
Where ce.CustomerEventDispositionID IS NOT NULL
Order By ce.CustomerEventDispositionDate Desc
-- Un-purge all of the records that were previously tied to a SUS077
Update IADS..CustomerEvent
Set CustomerEventDispositionID = Null,
CustomerEventDispositionComment = Null,
CustomerEventDispositionDate = Null,
UpdatedBy = #user,
UpdatedDate = GETDATE()
Where CustomerEventID In (Select CustomerEventID From #disposedRecords)
-- Remove the records from the PURGEEventsReadyForPurge table
Delete
From IADS..PURGEEventsReadyForPurge
Where CustomerEventID In (Select CustomerEventID From #disposedRecords)
-- Remove tie of purged records
Update IADS..CustomerEventHierarchy
Set EndDate = GETDATE(),
UpdatedBy = #user,
UpdatedDate = GETDATE()
Where CustomerEventHierarchyID In (Select CustomerEventHierarchyID From #disposedRecords)
Delete From IADS..PURGEEventsReadyForPurge Where PURGEEventsReadyForPurgeID In
(
Select PURGEEventsReadyForPurgeID
From IADS..PURGEEventsReadyForPurge p
Inner Join IADS..CustomerEvent ce On ce.CustomerEventID = p.CustomerEventID
And ce.CustomerEventDispositionID IS NULL
Inner Join IADS..CustomerEventCategory ceg On ceg.CustomerEventCategoryID = ce.CustomerEventCategoryID
Left Outer Join IADS..CustomerEventHierarchy ceh On ceh.CustomerEventID = ce.CustomerEventID
Left Outer Join IADS..CustomerEventHierarchy ceh2 On ceh2.RelatedCustomerEventID = ce.CustomerEventID
Where p.PurgeDate IS NOT NULL
)
Drop Table #disposedRecords
Drop Table #hiddata
Drop Table #surrogateHIDmap
Drop Table #surrogatemap
Drop Table #data
Commit
End Try
Begin Catch
Drop Table #disposedRecords
Drop Table #hiddata
Drop Table #surrogateHIDmap
Drop Table #surrogatemap
Drop Table #data
Rollback
End Catch
You can try any of these two things..
1. Update the compatiability level to 100.
ALTER DATABASE [dbname] SET COMPATIBILITY_LEVEL = 100
2. End the MERGE statement and the statement previous to MERGE with a semicolon (;)
Hope it works.

Implicit conversion of varchar value to varchar - collation conflict

I'm getting the following error whilst running this script. I've tried using the following:
COLLATE Latin1_General_CI_AS. Please can it be sorted? Thanks
Msg 457, Level 16, State 1, Line 8
Implicit conversion of varchar value to varchar cannot be performed because the collation of the value is unresolved due to a collation conflict
DECLARE #AccountID INT
SET #AccountID = 12
SELECT TOP 1 ac.AccountID,
co.Email,
ao.AccountOptionID
FROM CRM.acc.Account ac
INNER JOIN CRM.[profile].[Profile] pr
ON pr.ProfileID = ac.ProfileFK
INNER JOIN CRM.[profile].Contact co
ON pr.ProfileID = co.ProfileFK
LEFT JOIN CRM.acc.[AccountOption] ao
ON ao.AccountFK = ac.AccountID
LEFT JOIN (
SELECT OptionID
FROM CRM.acc.[Option]
WHERE [Name] = 'SMS messages') op
ON op.OptionID = ao.OptionFK
WHERE ac.AccountID = #AccountID
UNION ALL
SELECT u.UnsubscribeID,
u.EmailAddress,
u.SentEmailFK
FROM Email.dbo.Unsubscribe u
INNER JOIN (
SELECT CASE
WHEN AccountTypeFK = 2 THEN OnlineBillingEmail
ELSE EmailBillingEmail
END [EmailAddress]
FROM CRM.acc.Account
WHERE AccountID = #AccountID
) ace
ON ace.EmailAddress COLLATE DATABASE_DEFAULT = u.EmailAddress COLLATE DATABASE_DEFAULT
WHERE ISNULL(ace.EmailAddress, '') != ''
Seems that you have different collation types on your database. Then you can have issues when joining tables or to tables in other databases, as in this case. To get around this you can specify the collation of columns or force a collation using the COLLATE clause when joining two columns. Check more info about collation in MSDN
Also you need to specify the COLLATE clause where you are using the problematic column(s). Check this answer, it answer a very similar question
It is better to stick to a single collation globally. Otherwise you will have problems.
See a detailed explanation of the different collation styles
Edited: to check column collation use this snippet
SELECT name, collation_name
FROM sys.columns
WHERE OBJECT_ID IN (SELECT OBJECT_ID
FROM sys.objects
WHERE type = 'U'
AND name = 'your_table_name'
)
AND name = 'your_column_name'
Edited: added snippet to get all columns with different collation on a database
SELECT [TABLE_NAME] = OBJECT_NAME([id]),
[COLUMN_NAME] = [name],
[COLLATION_NAME] = collation
FROM syscolumns
WHERE collation <> 'your_database_collation_type'
AND collation IS NOT NULL
AND OBJECTPROPERTY([id], N'IsUserTable')=1
try this
ace.EmailAddress COLLATE Latin1_General_CI_AS = u.EmailAddress COLLATE Latin1_General_CI_AS
Because you are doing a union all to the CRM table which has a different collation. You need to explicitly define the collation of your columns going into your union. In your case that will be UnsubscribeID,EmailAddress and SentEmailFK all should be defined with collate database_default
Running the below should work. Let me know in the comments if this works
SELECT TOP 1 ac.AccountID,
co.Email,
ao.AccountOptionID
FROM CRM.acc.Account ac
INNER JOIN CRM.[profile].[Profile] pr
ON pr.ProfileID = ac.ProfileFK
INNER JOIN CRM.[profile].Contact co
ON pr.ProfileID = co.ProfileFK
LEFT JOIN CRM.acc.[AccountOption] ao
ON ao.AccountFK = ac.AccountID
LEFT JOIN (
SELECT OptionID
FROM CRM.acc.[Option]
WHERE [Name] = 'SMS messages') op
ON op.OptionID = ao.OptionFK
WHERE ac.AccountID = #AccountID
UNION ALL
SELECT u.UnsubscribeID COLLATE DATABASE_DEFAULT AS UnsubscribeID,
u.EmailAddress COLLATE DATABASE_DEFAULT AS EmailAddress ,
u.SentEmailFK COLLATE DATABASE_DEFAULT AS SentEmailFK
FROM Email.dbo.Unsubscribe u
INNER JOIN (
SELECT CASE
WHEN AccountTypeFK = 2 THEN OnlineBillingEmail
ELSE EmailBillingEmail
END [EmailAddress]
FROM CRM.acc.Account
WHERE AccountID = #AccountID
) ace
ON ace.EmailAddress COLLATE DATABASE_DEFAULT = u.EmailAddress COLLATE
DATABASE_DEFAULT
WHERE ISNULL(ace.EmailAddress, '') != ''

Resources