SQL Server 2005 date comparison - collation issues - sql

In my DB, I have a table that was created from an Excel sheet, via a Linked Server option.
I am now trying to compare its contents versus one of my main tables.
The tables I am comparing are in the same database.
There is a date column in both tables, both types are datetime and have Collation of SQL_Latin1_General_CP1_CI_AS, the same as the DB.
The server collation is Latin1_General_CI_AS
However when I try to run a query comparing the dates between the tables, I get the error:
Cannot resolve the collation conflict between
"Latin1_General_CI_AS" and
"SQL_Latin1_General_CP1_CI_AS" in the
equal to operation.
I have tried with and without the COLLATE option, using both collation settings.
My query is:
select * , hxl.holiday_dt,
datediff(d, h.holiday_dt collate SQL_Latin1_General_CP1_CI_AS,
hxl.holiday_dt collate SQL_Latin1_General_CP1_CI_AS)
from holiday h, Holiday_XL hxl
where h.currency_cd=hxl.currency_cd
In fact any query involving both tables gives exactly the same collation error, eg this one:
select count(*)
from Holiday_XL c
where c.currency_cd in (select distinct h.currency_cd from holiday h)
Thanks in advance for any thoughts.
Regards,
Chris

The error is being reported on the currency comparison h.currency_cd=hxl.currency_cd, not on datediff, so try force collation on the currencies.
Collation is only relevant for character (char, varchar, nvarchar) and text types.

Under the Collation and give the collation table level there are lot of tips and code available in net search with topic of collation.
Still if you have problem. Insert the content of the excel in to #table or permenant table and provide Collation to that table while selecting for comparison

Related

SQL Server Collation conflict in Georgian

I have database working on Georgia server and database collation is Georgian_Modern_Sort_CI_AS so when I try to do some select on this database I cannot do select queries because of collation problem because my data include also latin alphabet unfortunately I cannot select nvarchar items.
What can I do for not getting collation error?
you can change the collation on select with using COLLATE keyword.
SELECT *
FROM MyTable
where MyLatinColumn COLLATE Georgian_Modern_Sort_CI_AS = MyGeorgianColumn

Using COLLATE DATABASE_DEFAULT when querying the UNION when the table headers are unknown?

I am currently using code of the form
SELECT * FROM ##Temp1
UNION
SELECT * FROM ##Temp2
which (because the temporary tables are populated from tables in 2 different databases, which each use a different collation) results in the error message
Cannot resolve the collation conflict between "Latin1_General_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in the UNION operation.
Until now, when faced with an error such as this, I have been using the COLLATE DATABASE_DEFAULT method, which has been possible because the headings contained within the tables have been constant.
However, I am now faced with a collation conflict between 2 tables where the table headings are not constant. How might I resolve this issue?
One possible solution that I can think of is to loop through the table headers for ##Temp1 in the tempdb.dbo table and generate a string dynamically which specifies the column headings used in the temporary tables. However, this seems unneccessarily clumsy.

SQL collation conflict with temp table and procedure params coming from Delphi app

I've been working with MS SQL a few years now, and I've never encountered anything like this on my previous job. But where I work now, I got an error that I'd really like to know the cause from.
I made a stored procedure and called it in my Delphi 5 (yeah I know) app with some parameters. This worked fine on two databases (copies from different times). But now I tried it on another DB (again a copy), but it gave me the following error:
Cannot resolve the collation conflict between "Latin1_General_CI_AS" and
"SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
I got this by creating a temp table and then trying to insert some data. I'm not even joining. And the funny thing is: when I remove the whole WHERE clause, it works. When I leave it (although it only compares parameters with one table), it fails.
create table #TOP (EDAID int, ParentID char(30), ChildID char(30),
Position int, OrgQty_modified_manually bit)
This fails:
insert into #TOP
select EDAID, ParentID, ChildID, Position, OrgQty_modified_manually
from EDA_SOBOM
where OrderNr = #OrderNr
and Position = #Position
and LN = #LN
and DL = #DL
and rtrim(ChildID) = #CurrentPart
and rtrim(ParentID) = #ParentID
This works:
insert into #TOP
select EDAID, ParentID, ChildID, Position, OrgQty_modified_manually
from EDA_SOBOM
The procedure parameters are declared like this:
#PartID char(30), #Position int, #OrderNr char(8),
#LN char(2), #DL char(2), #ParentID char(30), #Modified bit output
I found a solution here: Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AS" in the equal to operation.
So I added this right after the CREATE:
ALTER TABLE #TOP
ALTER COLUMN ParentID
VARCHAR(30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
ALTER TABLE #TOP
ALTER COLUMN ChildID
VARCHAR(30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
And that made the whole thing work again...but I don't get it why the WHERE clause with only parameter comparisons fails...can parameters have collation too?
DB has collation SQL_Latin1_General_CP1_CI_AS.
Table EDA_SOBOM also has collation SQL_Latin1_General_CP1_CI_AS on the char columns.
I found this by the following query:
SELECT col.name, col.collation_name
FROM sys.columns col
WHERE object_id = OBJECT_ID('EDA_SOBOM')
Is there another place where collation can be set apart from the DB level and column level?
I wonder what's going on...
Collation conflicts come up on any operators that compare strings of different collations, i.e. the equals in your select.
TempDb takes the server default collation, whereas your real Dbs may have a different one, causing any temp tables created using DDL to have a collation difference.
You can add "collate database_default" clauses after your equality operators which should fix it.
Or you could create your temp table using:
select top 0 EDAID, ParentID, ChildID, Position, OrgQty_modified_manually
into #top
from EDA_SOBOM
This will force the temp table columns to take the data type (& collation) from your database.
There is a server level collation setting that acts as the default for all system dbs.
There is a database level collation, as you said.
And columns and expressions can have a collation defined.
Many problems arise when a database has a different collation from the system databases especially tempdb.
Without repeating Peter Wishart's answer, which I agree with, I would just add that when developing a product you should decide what level of collation flexibilty you are going to allow. To avoid problems you have to design code around that choice. If you are not going to require your database objects to be consistent with the server collation, then you have to apply collation modifiers or control the collations used when tables are created in tempdb, or system tables are used or when compares are done. That can be a lot of code in a large product.
There is another collation that is often overlooked in SQLServer. That is the default collation used in any .Net SPs or Functions. That collation is defined based on the SQLServer process's windows user profile. It's often not called a collation in docs, It's part of the windows regional settings. Called LCID in the registry.
So even if your database, sqlserver, table, column collations all match, you can still have mismatches if you do string compares in CLR stored procedure code, unless you write that code to avoid them.
To resolve the collation conflict add "COLLATE DATABASE_DEFAULT" keywords around “=” operator.
SELECT col.name, col.collation_name
FROM sys.columns col
WHERE object_id COLLATE DATABASE_DEFAULT = OBJECT_ID('EDA_SOBOM') COLLATE DATABASE_DEFAULT

SQL Server 2000 DTS - Cannot resolve collation conflict for equal to operation

I have a SQL Server 2000 DTS package.
One of the steps of this package has the following SQL:
SELECT *
FROM [Crocus_Limited$OrderRequestDetail]
WHERE (rep_updated > GETDATE() -2)
AND NOT EXISTS
(SELECT OrderID
FROM NavisionUpgrade.navision4.dbo.[WEBOrderDetails] rd
WHERE rd.OrderID = [Crocus_Limited$OrderRequestDetail].OrderID
AND rd.NavisionItemNo = [Crocus_Limited$OrderRequestDetail].NavisionItemNo )
It is failing- giving me error:
cannot resolve collation conflict for equal to operation.
This DTS basically moves data from one DB to another (located in different geographical locations)
how can i alter the above query to resolve this?
One or both of your join columns has on of the char datatypes (char,nchar,varchar,nvarchar) which is stored in incompatible collations in each database.
You can specify the collation to use in any string comparison. The easiest way to do it is to specify the default collation of the machine on which the query is running (I'm guessing that NavisionItemNo is the problem column):
...AND rd.NavisionItemNo collate database_default = [Crocus_Limited$OrderRequestDetail].NavisionItemNo collate database_default )
EDIT
Is OrderID a varchar column too? If so, try
...WHERE rd.OrderID collate database_default = [Crocus_Limited$OrderRequestDetail].OrderID collate database_default
AND rd.NavisionItemNo collate database_default = [Crocus_Limited$OrderRequestDetail].NavisionItemNo ) collate database_default
as the two former posts mention you have to use the collate attribute to every nonumeric column but have a look a the collation of the target db and use this collation (e.g. SQL_Latin_CI_AS). Be aware that a table can have it's own collation even a column can have annother collation, so have a deep look in your definitions.
Peace and good luck
Ice

SQL Server 2005 collation issue

I have two tables, and they are using different collations. It is not allowed to concatenate columns from tables with different collations, for example the following SQL is not allowed,
select table1column1 + table2column2 from ...
My question is, how to change the collation of a table without destroying the data of the table?
thanks in advance,
George
You can change columns collation on the fly if you need to.
E.g.
select table1column1 collate database default + table2column2 collate database default from ...
"Database default" could be whatever the collation you are wanting to use.
You can alter the collation of a column permanently with
ALTER TABLE ... ALTER COLUMN Table1Column1
varchar(50) COLLATE Latin1_General_CI_AS NOT NULL
GO