Is there an easier way of resolving SQL Server/database collation mismatches than changing every column?

Solution 1:

One option is to "proof" your code against collation mismatch.

You can use the special collation "DATABASE_DEFAULT" to coerce without knowing what the actual collation is. You use it on char type columns in temp tables, table variables and system tables you need to use.

Example:

CREATE TABLE #Currency (CCY CHAR(3))
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --error!
GO
-- in join too
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY COLLATE DATABASE_DEFAULT --no error
GO
DROP TABLE #Currency
GO


CREATE TABLE  #Currency (CCY CHAR(3) COLLATE DATABASE_DEFAULT)
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --no error!
GO

DROP TABLE #Currency
GO

This also means that when your clients migrate their DB onto a new whizzy SQL Server box with yet another different collation, it works too...

Solution 2:

Short answer is there is not an easy way. I've had the same issue in the past.

What I would say is 2 things, first when your customer sends you a database with an unexpected collation, install a new SQL instance with a default collation that matches their DB and work with it within that.

The second is make sure you app will work with other collations then the defaults (since those could change in the future) and work correctly as long as the collation on the SQL server and DB match. Then its fairly easy to have the customer install SQL server with a collation that matches their DB and will then work.

Or write a utility that will update all the tables, etc in your database as you said, but that might be more work then you want.

Solution 3:

If all the columns in the database are of the same collation then it will only cause problems for you when making cross-database queries (or your application is sort-order sensitive).

The sticky point comes when you realise that joining to temporary tables is cross-database, as they are in tempdb. That is easy to sort though - just make sure than any text columns in temporary tables are explicitly created with the COLLATE database_default directive. This means that the column will be created with the current database's default collation instead of tempdb's default collection (which will be the same as the server's default).