The database is case sensitive in unique constraints but not in select - sql-server

I have a SQL Server 2008 R2 Express and in the installation wizard I select the collation Modern_Spanish_CS_AS.
When I create a new database if I go to the properties of the database, I can see that the collation is correct, CS_AS.
However, when I do a select is not case sensitive and if I create a unique constraint I can't insert for example this strings: user01 and User01 because really the database is case insensitive.
Why if the server, the database and the table are case sensitive, the selections and the constraints not? In practice, is case insensitive.
How can I solve this problem? I would like that all the database was case sensitive.
Thanks.

I would take a look at this forum post and validate that the fields in your unique constraint are truly case-sensitive: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/6de23802-eb3b-4759-9d4d-a796c69e6271
You can query for the collation of the field (in case the table was created case-insensitive):
select name, collation_name
from sys.columns
where object_id in (select object_id from sys.objects where name = '<table name>') and name = '<field name>'
Post back if this doesn't resolve the issue and I can add some tests.

Related

SQL Server 'Invalid column' on a SELECT query to a temp table - CASE SENSITIVITY issue

I have a case where I have NO control whatsoever on the SQL Server configuration.
Here's my configuration:
SQL Server 2008
SQL Server INSTANCE Collation: Latin_General_BIN (Which I know is case-sensitive)
A given database (Which is not case-sensitive... SQL_Latin1_General_CP1_CI_AS)
Here's the scenario I want... if possible:
Given
CREATE DATABASE given_database;
USE given_database;
CREATE TABLE #test (Field1 nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS);
When
SELECT field1 FROM #test; /*Notice the lower case on field1*/
Then
Invalid column name 'field1'
Is there a way to make this work?
I know this is something that no one would want to have but since I am stuck with this configuration on my client side and we have a lot of legacy code that have different casing in the queries... I wanted to know if there's a work around.
Is there a way to make this work?
Not with a temp table, no.
Tempdb inherits the instance default collation. You've defined the column with a case insensitive collation which should let you ask for value comparisons in a case insensitive manner, but the column name itself falls into the database collation so it needs to be referred to as defined.
CREATE TABLE #test (Field1 nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS);
INSERT INTO #test
VALUES ('test'),('TEST'),('Test')
SELECT field1 FROM #test --should fail
SELECT Field1 FROM #test WHERE Field1 = 'tEst' --should work

SQL server key violation due to case insesitivity

I m having a table in which a primary key is there with 2 columns(CODE nvarchar,VALUE nvarchar).This table contains the values in the Key columns as (X8900,A) but when I try to insert a new value as (X8900,a) ,its giving error message “primary key violation”.
Why its giving this error,if case is different for values column and is there any solution for this in order avoid the error ?
You can specify if SQL Server should be case sensitive or not using collation. In this instance the column must have a case sensitive collation in order for you to be able to specify any type of unique constraint on it. For example, the first example will fail whereas the second will work, notice the CI and CS for case insensitive and sensitive.
CREATE TABLE test1 (
col1 varchar(20) COLLATE Latin1_General_CI_AS PRIMARY KEY
)
INSERT INTO test1 VALUES ('ASD')
INSERT INTO test1 VALUES ('asd')
CREATE TABLE test2 (
col1 varchar(20) COLLATE Latin1_General_CS_AS PRIMARY KEY
)
INSERT INTO test2 VALUES ('ASD')
INSERT INTO test2 VALUES ('asd')
Collation can be set at the column or database level. If set at database level then all character columns without a collation specified adopt the database collation.
You have to check the collation of your database. If you have a case insensitive collation, 'A' == 'a'. If you need to maintain difference between cases, you can either change the collation to a case sensitive collation, or you could cast the strings to varbinary. A binary representation differentiates between cases.
Collations can be set at the server level (i.e what databases default to) and at the database level (overriding the server collation). At an even more granular level, you can set collation on individual columns if you want/need. Here are a few articles to look at:
https://msdn.microsoft.com/en-us/library/hh230914.aspx#TsqlProcedure
https://msdn.microsoft.com/en-us/library/ms144250%28v=sql.105%29.aspx
Here are a few SQL snippets you can run to view your current server collation, as well as the default collations on each database
SELECT CONVERT (varchar, SERVERPROPERTY('collation'));
SELECT name, collation_name FROM sys.databases;

Query to change table collation in SQL Server 2008

In my database, one table collation is different than all the other tables.
I would like to change that table collation to be the same as all other tables.
Now, I can change a table collation by using SSMS Design but I would like to use query to change collation. Currently, my one table collation is Thai_CI_AS and I want to change collation is SQL_Latin1_General_CP1_CI_AS.
It's not possible to drop the table because it already contains data.
Never a bad idea to consult the documentation. Guessing at the source data type and NULLability; you can fill in the table/column names:
ALTER TABLE dbo.TableName ALTER COLUMN ColumnName
NVARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL;
If you can't check the documentation, Management Studio will sometimes show you the smart way to do something (though it doesn't always choose to do things the best way). Go into the design screen, change the collation, and instead of clicking OK, click the Script button.
This is a valid solution that I applied and tested resetting collation on one of jira database tables.
-- CHANGED COLUMN COLLATION PROPERLY
ALTER TABLE [schemaName].[TableName]
ALTER COLUMN [columnName] [varchar](255)
COLLATE SQL_Latin1_General_CP437_CI_AI NOT NULL;
--Check string column collation for specified table
--Lists all string columns with respective collation
SELECT c.name,
c.collation_name
FROM SYS.COLUMNS c
JOIN SYS.TABLES t ON t.object_id = c.object_id
WHERE t.name = 'TableName'
and c.collation_name is not null

Creating case sensitive catalog

I'm trying to create multiple rows having the same value but different case to a table with a Primary Key defined on a string column.
By default SQL server wouldn't allow you to do that, is there a way I can tell SQL server this is permitted?
By changing ‘Database Collation’ parameter we can control the database case sensitivity.
The default collation is SQL_Latin1_General_CP1_CI_AS (CI => Case-insensitive)
By changing to SQL_Latin1_General_CP1_CS_AS (CS => Case sensitive) you can enable 2 rows having same primary key with different case.
Specify the COLLATION of the column on your table to be case sensitive.
First figure out what collation your database is using.
SELECT DATABASEPROPERTYEX(DB_NAME(), 'Collation') AS CollationUsedBySQLServerDatabase
-- Mine was Finnish_Swedish_CI_AS
Pick the same one for your table, but choose it to be case sensitive (Finnish_Swedish_CS_AS)
create table Users
(
UserName varchar(5000) COLLATE Finnish_Swedish_CS_AS PRIMARY KEY
)
insert Users(UserName)
Values ('Peter'), ('PETER')
select * from Users

How to import Case-Sensitive data from Oracle to SQL Server using SSIS

I am trying to import data from Oracle into SQL Server using SSIS.
The problem is I have a PK of datatype VARCHAR2(200) in one of the tables having case-sensitive data in Oracle DB. Hence, the SSIS, while importing the data, is throwing
Violation of PK, cannot insert duplicate value in PK
How should I work around this? Any solution for this EXCEPT accepted answer of this because it's not feasible for me to drop and create the DB for enabling case-sensitive data?
You don't need to Recreate database. You just need to set Case Sensitive column.
Open in Design mode Table, choose your column and push Collation row.
Just check "Case Sensitive" checkbox, push OK and Save Table. now It will be OK.
If you can add a new column, set its collation to case sensitive one, reload the records and then rename them accordingly:
SELECT 1 AS TEST INTO #TT
ALTER TABLE #TT ADD new_pk_case_sensitive VARCHAR(200) COLLATE Latin1_General_CS_AS

Resources