This week I have a new little challenge by a customer.
By executing a “standard” stored procedure, I have the error:
Msg 468, Level 16, State 9, Procedure Get_logsessions, Line 56 [Batch Start Line 119]
Cannot resolve the collation conflict between “Latin1_General_CI_AS” and “Latin1_General_CI_AS_KS_WS” in the equal to operation.
The Stored Procedure named Get_Logsessions is to log all sessions running on the server in a table.
Looking with the query I develop and present you in a precedent blog here.
I can see that my database collation is not the same as the instance collation

Here the script for the Procedure:
CREATE PROCEDURE [dbo].[Get_logsessions]
AS
SET NOCOUNT ON
IF OBJECT_ID(N'[dbo].[logsessions]') IS NULL
BEGIN
CREATE TABLE [dbo].[logsessions]
(
[clientip] varchar(48),
[clientname] nvarchar(128) ,
[clientinterface] nvarchar(32) ,
[app] nvarchar(128) ,
[auth] nvarchar(40) ,
[login] nvarchar(128) ,
[db] nvarchar(128),
[firstaccess] [datetime] NULL,
[lastaccess] [datetime] NULL,
[count] bigint NULL
)
END
IF OBJECT_ID(N'tempdb..#sp_who2') IS NOT NULL
DROP TABLE #sp_who2
IF OBJECT_ID(N'tempdb..#logsessions') IS NOT NULL
DROP TABLE #logsessions
-- Use sp_who2 to be compatible with 2005 to replace [db] = db_name(b.database_id)
CREATE TABLE #sp_who2 (SPID INT,Status VARCHAR(255) ,
Login VARCHAR(255) ,HostName VARCHAR(255) ,
BlkBy VARCHAR(255) ,DBName VARCHAR(255) ,
Command VARCHAR(255) ,CPUTime INT,
DiskIO INT,LastBatch VARCHAR(255) ,
ProgramName VARCHAR(255) ,SPID2 INT,
REQUESTID INT)
INSERT INTO #sp_who2 EXEC sp_who2
SELECT DISTINCT
[clientip] = a.client_net_address,
[clientname] = b.host_name ,
[clientinterface] = b.client_interface_name ,
[app] = b.program_name ,
[auth] = a.auth_scheme ,
[login] = b.login_name ,
[db] = w.DBName ,
[firstaccess] = MIN(b.[login_time]),
[lastaccess] = MAX(b.[login_time]),
[count] = Count(*)
INTO
#logsessions
FROM
sys.dm_exec_connections a
INNER JOIN sys.dm_exec_sessions b on a.session_id = b.session_id
INNER JOIN #sp_who2 w on w.SPID = b.session_id
GROUP BY a.[client_net_address],b.[host_name] ,b.[client_interface_name],b.[program_name] ,a.[auth_scheme],b.[login_name],w.[DBName]
UPDATE
b
SET
b.[lastaccess] = a.[lastaccess],
b.[count] = b.[count] + 1
FROM
#logsessions a
INNER JOIN [dbo].[logsessions] b
ON a.[clientip] = b.[clientip]
AND a.[clientname] = b.[clientname]
AND a.[clientinterface] = b.[clientinterface]
AND a.[app] = b.[app]
AND a.[auth] = b.[auth]
AND a.[login] = b.[login]
AND a.[db] = b.[db]
WHERE
DATEDIFF(s,b.[lastaccess] ,a.[lastaccess]) <> 0
AND
DATEDIFF(s,b.[firstaccess] ,a.[firstaccess]) <> 0
AND
DATEDIFF(s,b.[firstaccess] ,a.[lastaccess]) > 0
INSERT INTO [dbo].[logsessions]
(
[clientip]
,[clientname]
,[clientinterface]
,[app]
,[auth]
,[login]
,[db]
,[firstaccess],
[lastaccess],
[count]
)
(
SELECT
a.[clientip],a.[clientname] ,a.[clientinterface],a.[app] ,a.[auth], a.[login],a.[db], a.[firstaccess],a.[lastaccess],a.count
FROM #logsessions a
LEFT JOIN [dbo].[logsessions] b
ON a.[clientip] = b.[clientip]
AND a.[clientname] = b.[clientname]
AND a.[clientinterface] = b.[clientinterface]
AND a.[app] = b.[app]
AND a.[auth] = b.[auth]
AND a.[login] = b.[login]
AND a.[db] = b.[db]
WHERE
b.[clientip] IS NULL
)
DROP TABLE #logsessions
DROP TABLE #sp_who2
SET NOCOUNT OFF
GO
If I comment the creation of the Stored Procedure and I execute the query , I see my collation conflict:

If I go to the line 67, I’m on the update command:
UPDATE
b
SET
b.[lastaccess] = a.[lastaccess],
b.[count] = b.[count] + 1
FROM
#logsessions a
INNER JOIN [dbo].[logsessions] b
ON a.[clientip] = b.[clientip]
AND a.[clientname] = b.[clientname]
AND a.[clientinterface] = b.[clientinterface]
AND a.[app] = b.[app]
AND a.[auth] = b.[auth]
AND a.[login] = b.[login]
AND a.[db] = b.[db]
WHERE
DATEDIFF(s,b.[lastaccess] ,a.[lastaccess]) 0
AND
DATEDIFF(s,b.[firstaccess] ,a.[firstaccess]) 0
AND
DATEDIFF(s,b.[firstaccess] ,a.[lastaccess]) > 0
The conflict comes from the update from the table #logsessions to logsessions and the collation from the comparison between the varchar columns from each table in the join.
What can I do?
I will simply aligned the collation for each column with
COLLATE DATABASE_DEFAULT
My new update will be like this:
UPDATE
b
SET
b.[lastaccess] = a.[lastaccess],
b.[count] = b.[count] + 1
FROM
#logsessions a
INNER JOIN [dbo].[logsessions] b
ON a.[clientip] = b.[clientip] COLLATE DATABASE_DEFAULT
AND a.[clientname] = b.[clientname] COLLATE DATABASE_DEFAULT
AND a.[clientinterface] = b.[clientinterface] COLLATE DATABASE_DEFAULT
AND a.[app] = b.[app] COLLATE DATABASE_DEFAULT
AND a.[auth] = b.[auth] COLLATE DATABASE_DEFAULT
AND a.[login] = b.[login] COLLATE DATABASE_DEFAULT
AND a.[db] = b.[db] COLLATE DATABASE_DEFAULT
WHERE
DATEDIFF(s,b.[lastaccess] ,a.[lastaccess]) 0
AND
DATEDIFF(s,b.[firstaccess] ,a.[firstaccess]) 0
AND
DATEDIFF(s,b.[firstaccess] ,a.[lastaccess]) > 0
And when I execute the script, no more conflict

I do an alter Store Procedure and execute this new one:

Perfect no more collation conflict!
I think that is important to share with you this issue and hope you will win time if you need to resolve a similar case.
