collation conflict sql server - sql

When i issue a SQL query, sometimes I get the following error message:
Cannot resolve the collation conflict between "Latin1_General_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
I often solve this problem just make both table collation same. so i need to know is there any quick way to fix this issue.
I'd like to put something special in my SQL query as a result if collation is not same for both table in sql query then also query will work perfectly without any error. is there any solution?

You can force which collation by using the COLLATE clause.
i.e.
SELECT *
FROM Table1 T1
INNER JOIN Server2.dbo.Table2 T2
ON T1.Name = T2.Name COLLATE database_default
Collation conflicts are common when joining tables between two databases or servers, especially if the version of the DB is different.

You can specify a collation in a query using the collate clause:
where col1 = col2 collate Latin1_General_CI_AS

There could be a possibility that both the servers use different Collations. If yes then you would get an error similar to then one I mentioned at the top of this topic. What you should do in this case?
You can alter the default Collation of either of the table columns/fields, but this could have a ripple effect for other tables currently in use with the altered table.
Use COLLATE DATABASE_DEFAULT keyword while matching the columns/fields
like:
SELECT T1.EmployeeName, T2.DeptName
FROM ServerA.dbo.EmpTab T1
JOIN ServerB.dbo.DeptTab T2
ON T1.DeptCode COLLATE DATABASE_DEFAULT
= T2.DeptCode COLLATE DATABASE_DEFAULT

Related

Firebird order by collation

I am with strange problem with Firebird 2.5.
My database has default charset = utf8.
I have a column p_nname in patienten table:
CREATE TABLE PATIENTEN (
P_NNAME VARCHAR(25) DEFAULT '' NOT NULL COLLATE UNICODE_CI,
I expect collation to work everywhere. I mean in WHERE and ORDER BY clauses.
What I have is working collation in WHERE. Two queries below give me similar result and it is good.
select * from patienten where p_nname='adler'
select * from patienten where p_nname='ADler'
Problem is ORDER BY clause does not work as I expect.
This SQL works as if the column has no UNICODE_CI collation.
select * from patienten order by p_nname
To get the needed result with good sorting I have to write so:
select * from patienten order by p_nname collate unicode_ci
Is there a way to omit COLLATE flag in ORDER BY clause?
Looks like a bug indeed, the documentation states:
The keyword COLLATE specifies the collation order for a string column
if you need a collation that is different from the normal one for this
column. The normal collation order will be either the default one for
the database character set or one that has been set explicitly in the
column's definition.
so it should work without specifing the collate clause in ORDER BY. I suggest you file a bug report.

How to use EXCEPT clause in multiple databases

I have a query with an except clause. Underneath the except, my 2nd query is coming from a different database than the one that the first query is using.
It looks something like this
SELECT field1 as a
FROM table 1
EXCEPT
USE differentdb
SELECT field2 as a
FROM table 2
I have also tried this
SELECT field1 as a
FROM table 1
EXCEPT
USE differentdb
SELECT field2 as a
FROM differentdb.dbo.table2
I realize that this is not allowed in SQL because I get the following error:
Msg 468, Level 16, State 9, Line 1 Cannot resolve the collation
conflict between "SQL_Latin1_General_CP1_CI_AS" and
"Latin1_General_CI_AS" in the equal to operation.
I am wondering if there is another way to write this query and accomplish a cross-db EXCEPT clause.
Change the collation of column on the fly like:
SELECT field1 COLLATE SQL_Latin1_General_CP1_CI_AS as a
FROM table 1
EXCEPT
SELECT differentdb.SchemaName.field2 as a
FROM table 2
Us can use collate clause to convert collation from other database.
SELECT field2 collate SQL_Latin1_General_CP1_CI_AS as a
FROM table 2
Here you should use correct collation - because it is not enough information what is collation of your first and second databases.
Or you can simply use
SELECT field2 collate database_default as a
FROM table 2
This will cause the collate clause to inherit the collation of the current database

How to change collation of a linked server or collation of a table

Is it possible to change a collation of a linked server?
I have to JOIN two tables. TableA is on a linked server with different collation then TableB which is on my local server. If it is not possible to change collation of an entire server maybe it could be possible to change the collation of Results based on TableA.
You can change the collation for the purposes of the join. The syntax would be something like this:
Select *
From TableA
Inner Join TableB
On TableA.StringColumn = TableB.StringColumn Collate Collation_Name_Here

Is the LIKE operator case-sensitive with SQL Server?

In the documentation about the LIKE operator, nothing is told about the case-sensitivity of it. Is it? How to enable/disable it?
I am querying varchar(n) columns, on an Microsoft SQL Server 2005 installation, if that matters.
It is not the operator that is case sensitive, it is the column itself.
When a SQL Server installation is performed a default collation is chosen to the instance. Unless explicitly mentioned otherwise (check the collate clause bellow) when a new database is created it inherits the collation from the instance and when a new column is created it inherits the collation from the database it belongs.
A collation like sql_latin1_general_cp1_ci_as dictates how the content of the column should be treated. CI stands for case insensitive and AS stands for accent sensitive.
A complete list of collations is available at https://msdn.microsoft.com/en-us/library/ms144250(v=sql.105).aspx
(a) To check a instance collation
select serverproperty('collation')
(b) To check a database collation
select databasepropertyex('databasename', 'collation') sqlcollation
(c) To create a database using a different collation
create database exampledatabase
collate sql_latin1_general_cp1_cs_as
(d) To create a column using a different collation
create table exampletable (
examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
)
(e) To modify a column collation
alter table exampletable
alter column examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
It is possible to change a instance and database collations but it does not affect previously created objects.
It is also possible to change a column collation on the fly for string comparison, but this is highly unrecommended in a production environment because it is extremely costly.
select
column1 collate sql_latin1_general_cp1_ci_as as column1
from table1
All this talk about collation seem a bit over-complicated. Why not just use something like:
IF UPPER(##VERSION) NOT LIKE '%AZURE%'
Then your check is case insensitive whatever the collation
If you want to achieve a case sensitive search without changing the collation of the column / database / server, you can always use the COLLATE clause, e.g.
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CS_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 1 row
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CI_AS LIKE 'j%';
-- 2 rows
GO
DROP TABLE dbo.foo;
Works the other way, too, if your column / database / server is case sensitive and you don't want a case sensitive search, e.g.
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CI_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 2 rows
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CS_AS LIKE 'j%';
-- 1 row
GO
DROP TABLE dbo.foo;
You have an option to define collation order at the time of defining your table. If you define a case-sensitive order, your LIKE operator will behave in a case-sensitive way; if you define a case-insensitive collation order, the LIKE operator will ignore character case as well:
CREATE TABLE Test (
CI_Str VARCHAR(15) COLLATE Latin1_General_CI_AS -- Case-insensitive
, CS_Str VARCHAR(15) COLLATE Latin1_General_CS_AS -- Case-sensitive
);
Here is a quick demo on sqlfiddle showing the results of collation order on searches with LIKE.
The like operator takes two strings. These strings have to have compatible collations, which is explained here.
In my opinion, things then get complicated. The following query returns an error saying that the collations are incompatible:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' COLLATE SQL_Latin1_General_CP1_CI_AS like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
On a random machine here, the default collation is SQL_Latin1_General_CP1_CI_AS. The following query is successful, but returns no rows:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
The values "abc" and "ABC" do not match in a case-sensitve world.
In other words, there is a difference between having no collation and using the default collation. When one side has no collation, then it is "assigned" an explicit collation from the other side.
(The results are the same when the explicit collation is on the left.)
Try running,
SELECT SERVERPROPERTY('COLLATION')
Then find out if your collation is case sensitive or not.
You can change from the property of every item.
You can easy change collation in Microsoft SQL Server Management studio.
right click table -> design.
choose your column, scroll down i column properties to Collation.
Set your sort preference by check "Case Sensitive"

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