Creating case sensitive catalog - sql-server

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

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

"Cannot resolve collation conflict" even after fixing the collation

The current database I'm using "PrimaryDatabase" has the collation "SQL_Latin1_General_CP1_CI_AS", while the "SecondaryDatabase" I'm trying to access has the collation "Arabic_CI_AS"
I changed the collation for the SecondaryDatabase and set it to " SQL_Latin1_General_CP1_CI_AS" and made sure it has been changed as well as in its tables.
However, when i run the query below I still get collation conflict.
select * from [MYSERVER].[SecondaryDatabase].[dbo].[SecondaryTableName]
where ltrim(rtrim([SecondaryTablename])) not in (select ltrim(rtrim(PrimaryFieldname)) from PrimaryTablename where PrimaryFieldName2=1)
One way to make your query work is to use COLLATE clause in order to apply a collation cast on both fields being involved in the predicate of the WHERE clause:
select *
from [MYSERVER].[SecondaryDatabase].[dbo].[SecondaryTableName]
where ltrim(rtrim([SecondaryFieldname])) COLLATE SQL_Latin1_General_CP1_CI_AS
not in (select ltrim(rtrim(PrimaryFieldname)) COLLATE SQL_Latin1_General_CP1_CI_AS
from PrimaryTablename
where PrimaryFieldName2 = 1)
The COLLATE clause applied to PrimaryFieldname might not be necessary, since this is the default collation of the corresponding database (so probably PrimaryFieldname already has this collation).
Another solution is to change the collation at field level, e.g.:
ALTER TABLE SecondaryDatabase
ALTER COLUMN SecondaryFieldname VARCHAR(50)
COLLATE SQL_Latin1_General_CP1_CS_AS NULL

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;

The database is case sensitive in unique constraints but not in select

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.

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