August 24, 2005 at 6:43 am
Hello there,
I have a collation conflict between a database table and a UDF table variable in the same database.
I have a production server running 2000 standard edition which has a server collation of SQL_Latin1_General_CP1_CI_AS.
I recently installed a training server, but the CD I had available only gave me the option of Latin1_General when I installed, giving a server collation of Latin1_General_CI_AS.
So I created a blank copy of my production database and set the collation to SQL_Latin1_General_CP1_CI_AS using ALTER DATABASE ...COLLATE ...
Then I copied the production database into the blank training database using DTS. Everything copied successfully except the UDF I have listed below, which failed. When I tried to apply it manually, I got 'Error 446: Cannot resolve collation conflict for equal to operation'.
The problem occurs in the WHERE ManagerID IN part of the INSERT. I am guessing that the conflict might arise because the collation of the table variable @Reports does not match the collation of the database table CurrentContract to which I am joining it. Do table variables therefore assume the collation setting of the server or of the tempdb database ?
I cannot change the collation setting for tempdb, because it is a system database.
So is there any way I can change the table variable collation, or can I force the installation to use a collation which is not listed in the install program drop-down?
Much obliged for any suggestions,
David
FYI: The function returns a list of employee IDs who report directly or indirectly to the employee ID passed as a parameter.
==============Function====================
CREATE FUNCTION ctfn_LineReports (@strUserID CHAR(8))
RETURNS @Reports TABLE (userid CHAR(8), orglevel INTEGER, managerid CHAR(8))
AS
BEGIN
DECLARE @intOrgLevel INTEGER
SET @intOrgLevel=0
INSERT INTO @Reports (userid, orglevel, managerid)
SELECT @strUserID, @intOrgLevel, managerid
FROM currentcontract WITH (NOLOCK)
WHERE userid=@strUserID
WHILE (SELECT COUNT(*) FROM @Reports WHERE 0">orglevel=@intOrgLevel)>0 AND @intOrgLevel<10
BEGIN
SET @intOrgLevel=@intOrgLevel+1
INSERT INTO @Reports (userid, orglevel, managerid)
SELECT userID, @intOrgLevel, managerid
FROM CurrentContract WITH (NOLOCK)
--Problem in this WHERE clause
WHERE ManagerID IN
(SELECT UserID FROM @Reports WHERE orglevel=@intOrgLevel-1)
AND UserID NOT IN
(SELECT UserID FROM @Reports)
END
RETURN
END
If it ain't broke, don't fix it...
August 24, 2005 at 8:59 am
You can use "collate" in the where clause to join fields with dis-similar collations.
How about:
INSERT INTO @Reports (userid, orglevel, managerid)
SELECT userID, @intOrgLevel, managerid
FROM CurrentContract WITH (NOLOCK)
--Problem in this WHERE clause
WHERE ManagerID COLLATE Latin1_General_CI_AS IN -- or vice versa
(SELECT UserID FROM @Reports WHERE orglevel=@intOrgLevel-1)
AND UserID NOT IN
(SELECT UserID FROM @Reports)
August 24, 2005 at 10:09 am
Hi, thanks for that. I didn't realise you could use COLLATE at the column level too.
Your suggestion worked, I also tried the following, which also worked and could be applied to my production database so that I can run the DTS export without errors.
RETURNS @Reports TABLE (userid CHAR(8) COLLATE SQL_Latin1_General_CP1_CI_AS, orglevel INTEGER, managerid CHAR(8) COLLATE SQL_Latin1_General_CP1_CI_AS)
Many thanks
David
If it ain't broke, don't fix it...
Viewing 3 posts - 1 through 2 (of 2 total)
You must be logged in to reply to this topic. Login to reply