Obviously, the problem is here:
replace(p.Password,p.Password,d.Code+p.Password)
If we look at the collations involved:
replace(Latin1_General_BIN, Latin1_General_BIN, [!]Latin1_General_CI_AI + Latin1_General_BIN[/!])
So, we're trying to concatenate two different collations. If we use the COLLATE clause, the problem goes away. Like this:
Code:
update p
set p.Password = replace(p.Password,p.Password,d.Code [!] COLLATE Latin1_General_BIN[/!] +p.Password)
from Password p
join DealerEmployee de on de.Id_User = p.Id_User
join Dealer d on d.Id_Dealer = de.Id_Dealer
where p.Password = 'xxxxx'
Here's a (some what) similar example, with some dummy tables and data.
Code:
Declare @Password Table(UserId Int, Password VarChar(50) Collate Latin1_General_BIN)
Declare @User Table(UserId Int, Name VarChar(20) Collate Latin1_General_CI_AI)
Insert Into @User Values(1, 'George')
Insert Into @User Values(2, 'Dan')
Insert Into @Password Values(1, 'Foo')
Insert Into @Password Values(2, 'Bar')
Update P
Set P.Password = Replace(P.Password, P.Password, U.Name + P.Password)
From @Password P
Inner Join @User U
On P.UserId = U.UserId
Select * From @Password
When you run the code above, you will get this error:
[tt][red]Implicit conversion of varchar value to varchar cannot be performed because the collation of the value is unresolved due to a collation conflict.[/red][/tt]
But, if you modify the code slightly (to this), it works.
Code:
Declare @Password Table(UserId Int, Password VarChar(50) Collate Latin1_General_BIN)
Declare @User Table(UserId Int, Name VarChar(20) Collate Latin1_General_CI_AI)
Insert Into @User Values(1, 'George')
Insert Into @User Values(2, 'Dan')
Insert Into @Password Values(1, 'Foo')
Insert Into @Password Values(2, 'Bar')
Update P
Set P.Password = Replace(P.Password, P.Password, U.Name [!]Collate Latin1_General_BIN[/!] + P.Password)
From @Password P
Inner Join @User U
On P.UserId = U.UserId
Select * From @Password
Most programmers know that SQL Server can do data type conversions for you, but that it's best not to rely upon this. It's better to convert things for yourself.
For example, what is the output of the following code:
[tt]Select '10' + 20[/tt]
There are really only 2 (reasonable) choices. It's either 30 or '1020'. In this example, if you want to add as numbers, it's better to cast/convert the string to a number. If you want string concatenation, it's better to cast/convert the number to a string.
Similarly with strings that have different collations, it's better to specify the collation. This isn't always necessary, but whenever you concatenate and/or compare strings with different collations, it's better to specify the collation instead of relying upon SQL Server to do it for you.
Make sense?
-George
Microsoft SQL Server MVP
My Blogs
SQLCop
"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom