SQL change field Collation in a select - sql-server

i'm trying to do the following select:
select * from urlpath where substring(urlpathpath, 3, len(urlpathpath))
not in (select accessuserpassword from accessuser where accessuserparentid = 257)
I get the error:
Cannot resolve the collation conflict between
"SQL_Latin1_General_CP1_CI_AI" and
"SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
Does anyone know how i can cast as a collation, or something that permits me to match this condition?
Thanx

You can add COLLATE CollationName after the column name for the column you want to "re-collate". (Note: the collation name is literal, not quoted)

You can even do the collate on the query to create a new table with that query, for example:
SELECT
*
INTO
#TempTable
FROM
View_total
WHERE
YEAR(ValidFrom) <= 2007
AND YEAR(ValidTo)>= 2007
AND Id_Product = '001'
AND ProductLine COLLATE DATABASE_DEFAULT IN (SELECT Product FROM #TempAUX)
COLLATE DATABASE_DEFAULT causes the COLLATE clause inherits the collation of the current database, eliminating the difference between the two

Related

unexpected output sql server using count

I am using sql-server 2012
The query is :
CREATE TABLE TEST ( NAME VARCHAR(20) );
INSERT TEST
( NAME
)
SELECT NULL
UNION ALL
SELECT 'James'
UNION ALL
SELECT 'JAMES'
UNION ALL
SELECT 'Eric';
SELECT NAME
, COUNT(NAME) AS T1
, COUNT(COALESCE(NULL, '')) T2
, COUNT(ISNULL(NAME, NULL)) T3
, COUNT(DISTINCT ( Name )) T4
, COUNT(DISTINCT ( COALESCE(NULL, '') )) T5
, ##ROWCOUNT T6
FROM TEST
GROUP BY Name;
DROP TABLE TEST;
In the result set ther is no 'JAMES' ? (caps)
please tell how this was excluded
expected was Null,james,JAMES,eric
You need to change your Name column collation to Latin1_General_CS_AS which is case sensitive
SELECT NAME COLLATE Latin1_General_CS_AS,
Count(NAME) AS T1,
Count(COALESCE(NULL, '')) T2,
Count(Isnull(NAME, NULL)) T3,
Count(DISTINCT ( Name )) T4,
Count(DISTINCT ( COALESCE(NULL, '') )) T5,
##ROWCOUNT T6
FROM TEST
GROUP BY Name COLLATE Latin1_General_CS_AS;
Use a sensitive case collation like COLLATE Latin1_General_CS_AS.
CREATE TABLE TEST ( NAME VARCHAR(20) COLLATE Latin1_General_CS_AS );
The other people who commented here are correct.
It would be easier for you to understand their meaning if you googled for collation and case sensitivity, but in layman's terms it's like this:
Collation is a little like encoding; It determines how the characters in string columns are interpreted, ordered and compared to one another. Case insensitive means that UPPERCASE / lowercase are considered exactly the same, so for instance 'JAMES', 'james', 'JaMeS' etc would be no different to SQL Server. So when your database has a case-insensitive collation and you then create a table with a column without defining the collation, that column will inherit the default collation used by the database, which is how we arrived here.
You can manually alter a column collation, or define it during a query, but bear in mind that whenever you compare two different columns, you need to assign both of them to use the same collation, or you will get an error. That's why it's good practice to pretty much use the same collation throughout the database barring special query-specific circumstances.
To your question regarding what Latin1_General_CS_AS means, it basically means "Latin1_General" alphabet, the details of which you can check online. The "CS" part means case-sensitive, if it were case-insensitive you would see "CI" instead. The "AS" means accent-sensitivity, and "AI" would mean accent-insensitivity. Basically, whether 'Á' is considered to be equal to 'A', or not.
You can read a lot more about it from the source, here.

Cannot resolve the collation conflict between "Latin1_General_CI_AI" and "SQL_Latin1_General_CP1_CI_AS" in the equal to operation

I am trying to create a procedure in SQL Server 2008R2 but it is showing this error
Cannot resolve the collation conflict between "Latin1_General_CI_AI"
and "SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
The procedure that I have created is
CREATE Procedure Ps_Quiz_OnlineTest_QuestionsWithOptions_Get --'Ques1'
#Ques Varchar(8000)
As
Begin
Select
A.QuestionId,
A.QsnDesc,
A.CorrectOption,
B.OptionValue,
A.Marks,
(
Select QsnName
From Quiz_tblQsnsLimitMaster
Where QsnId = #Ques) QuesPaper,
(
Select Durationoftest
From Quiz_tblQsnsLimitMaster
Where QsnId = #Ques) QuesPaper
From
Quiz_tblQsnCreationMaster A,
Quiz_tblQsnCreationDetail B
Where
A.QuestionId = B.QuestionId
And A.QuestionId In (
Select QuestionIds
From FN_Question_Answers_Quiz(#Ques))
And B.QuestionId In (
Select QuestionIds
From FN_Question_Answers_Quiz(#Ques))
Order By
A.QuestionId,
B.OptionOrder
End
I tried to collate tables with different collations but it did not worked.
How can I solve this.
probably this might help, change your where condition like this
Where A.QuestionId COLLATE DATABASE_DEFAULT = B.QuestionId COLLATE DATABASE_DEFAULT
Since you've mentioned that QuestionID in each table is varchar, it's probably the comparison between those. So at a guess, try changing the line:
Where A.QuestionId = B.QuestionId And
To the following:
Where A.QuestionId = B.QuestionId COLLATE SQL_Latin1_General_CP1_CI_AS And
I'd prefer it if you used proper join syntax for your tables - but that's for another day ;-)
try use this,
where fieldname COLLATE DATABASE_DEFAULT = secondfieldname COLLATE DATABASE_DEFAULT
this is working
Just use the following syntax when joining tables with different collations,
where A.QuestionId collate SQL_Latin1_General_CP1_CI__AS = B.QuestionId collate
SQL_Latin1_General1_General_CP1_CI_AS
To overcome this use the below code:
SELECT NAME
FROM sys.objects
WHERE NAME COLLATE DATABASE_DEFAULT NOT IN (SELECT TYPE
FROM sys.objects)
I was facing same issue after migration of Database and shifting of server by service provider. So as solution I have created new database using CPanel then execute SQL query for schema and data to restore. Finally this issue got resolved.

Collation conflict with temp table

The collation of tempdb is Latin1_General_100_CI_AI. The collation of the database is also Latin1_General_100_CI_AI. Yet the following SQL statement:
SELECT *
FROM ##CitiesMapping AS cm
INNER JOIN Cities ON cm.CityName=Cities.Name
returns:
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_100_CI_AI" in the equal to operation.
The server default collation is also Latin1_General_100_CI_AI
It is possible that the collation is set differently for a single column. The query from Stuart will show you that. If they are different collations you can specify the collation being used on either side of the comparison like this:
SELECT *
FROM ##CitiesMapping AS cm
INNER JOIN Cities
ON cm.CityName COLLATE DATABASE_DEFAULT = Cities.Name COLLATE DATABASE_DEFAULT;
I hope this helps you out.
Check the tables involved as well:
SELECT name, collation_name, OBJECT_NAME(object_id)
FROM sys.columns
WHERE OBJECT_NAME(object_id) IN ('Cities')

SQL-Server is ignoring my COLLATION when I'm using LIKE operator

I'm working with Spanish database so when I'm looking for and "aeiou" I can also get "áéíóú" or "AEIOU" or "ÁÉÍÓÚ", in a where clause like this:
SELECT * FROM myTable WHERE stringData like '%perez%'
I'm expencting:
* perez
* PEREZ
* Pérez
* PÉREZ
So I changed my database to collation: Modern_Spanish_CI_AI
And I get only:
* perez
* PEREZ
But if I do:
SELECT * FROM myTable WHERE stringData like '%perez%' COLLATE Modern_Spanish_CI_AI
I get all results OK, so my question is, why if my database is COLLATE Modern_Spanish_CI_AI I have to set the same collation to my query???
I'm using SQL-Server 2008
You can use COLLATE, eg.
SELECT *
FROM TableName
WHERE strData COLLATE Latin1_general_CI_AI = 'perez' COLLATE Latin1_general_CI_AI
both sides must have the same collation.
SQLFiddle Demo
SQLFiddle Demo (using LIKE)
Others:
Selecting a SQL Server Collation
You need to change the collation of the table COLUMN itself.
select collation_name, *
from sys.columns
where object_id = object_id('tblname')
and name = 'stringdata';
If you're lucky it is as easy as (example)
alter table tblname alter column stringdata varchar(20) collate Modern_Spanish_CI_AS
But if you have constraints and/or schema bound references, it can get complicated.
It can be very difficult to work with a database with mixed collations, so you may want to re-collate all the table columns.

How to set collation for a connection in SQL Server?

How can i set the collation SQL Server will use for the duration of that connection?
Not until i connect to SQL Server do i know what collation i want to use.
e.g. a browser with language fr-IT has connected to the web-site. Any queries i run on that connection i want to follow the French language, Italy variant collation.
i envision a hypothetical connection level property, simlar to SET ANSI_NULLS OFF, but for collation1:
SET COLLATION_ORDER 'French_CI_AS'
SELECT TOP 100 FROM Orders
ORDER BY ProjectName
and later
SELECT * FROM Orders
WHERE CustomerID = 3277
AND ProjectName LIKE '%l''ecole%'
and later
UPDATE Quotes
SET IsCompleted = 1
WHERE QuoteName = 'Cour de l''école'
At the same time, when a chinese customer connects:
SET COLLATION_ORDER Chinese_PRC_CI_AI_KS_WS
SELECT TOP 100 FROM Orders
ORDER BY ProjectName
or
SELECT * FROM Orders
WHERE CustomerID = 3277
AND ProjectName LIKE '學校'
or
UPDATE Quotes
SET IsCompleted = 1
WHERE QuoteName = '學校的操場'
Now i could alter every SELECT statement in the system to allow me to pass in a collation:
SELECT TOP 100 FROM Orders
WHERE CustomerID = 3278
ORDER BY ProjectName COLLATE French_CI_AS
But you cannot pass a collation order as a parameter to a stored procedure:
CREATE PROCEDURE dbo.GetCommonOrders
#CustomerID int, #CollationOrder varchar(50)
AS
SELECT TOP 100 FROM Orders
WHERE CustomerID = #CustomerID
ORDER BY ProjectName COLLATE #CollationOrder
And the COLLATE clause can't help me when performing an UPDATE or a SELECT.
Note: All string columns in the database all are already nchar, nvarchar or ntext. i am not talking about the default collation applied to a server, database, table, or column for non-unicode columns (i.e. char, varchar, text). i am talking about the collation used by SQL Server when comparing and sorting strings.
How can i specify per-connection collation?
See also
Similar question, but for ADO.net and connection strings
Similar question, but for ASP.net MVC2 and MySQL
1 hypothetical sql that exhibits locale issues
As marc_s commented, the collation is a property of a database or a column, and not of a connection.
However, you can override the collation on statement level using the COLLATE keyword.
Using your examples:
SELECT * FROM Orders
WHERE CustomerID = 3277
AND ProjectName COLLATE Chinese_PRC_CI_AI_KS_WS LIKE N'學校'
UPDATE Quotes
SET IsCompleted = 1
WHERE QuoteName COLLATE Chinese_PRC_CI_AI_KS_WS = N'學校的操場'
Still, I cannot find a statement on using COLLATE with a dynamic collation name, leaving as only possible solution dynamic SQL and EXEC. See this social.MSDN entry for an example.

Resources