views:

2084

answers:

4

How can I check to see if an SQL Server is case sensitive? I have previously been running the query:

SELECT CASE WHEN 'A' = 'a' THEN 'NOT CASE SENSITIVE' ELSE 'CASE SENSITIVE' END

But I am looking for other ways as this has actually given me issues in the past.

Edit - A little more info: An existing product has many pre-written Stored Proc's. In a stored proc @test != @TEST depending on the sensitivity of the Server itself. So what im looking for is the best way to check the server for its sensitivity.

A: 

SQL Server is not case sensitive. SELECT * FROM SomeTable is the same as SeLeCT * frOM soMetaBLe.

Mark Callison
That's not what he's talking about. He means how _data_ is compared, not how code is processed.
Joel Coehoorn
I think the question is about comparing data in a case-insensitive way - not whether T-SQL statements are case-sensitive.
Vinay Sajip
The way it is worded, it sounds like he was asking if it was case sensitive. I think the down vote is a little unfair there.
Mark Callison
The query he provided makes it pretty clear what he's asking about.
Cybergibbons
I guess we will have to agree to disagree on that one
Mark Callison
Looking at the OPs recent edit where he's talking about parameters and variables of mixed case, I think Mark's got a valid point here. It's not purely data in columns. Going to +1.
Chris J
+1  A: 
Joel Coehoorn
+4  A: 

Collation can be set at various levels:

  1. Server
  2. Database
  3. Column

So you could have a Case Sensitive Column in a Case Insensitive database. I have not yet come across a situation where a business case could be made for case senstivity of a single column of data, but I suppose there could be.

Check Server Collation

SELECT SERVERPROPERTY('COLLATION')

Check Database Collation

SELECT DATABASEPROPERTYEX('AdventureWorks', 'Collation') SQLCollation;

Check Column Collation

select table_name, column_name, collation_name
from information_schema.columns
where table_name = @table_name
Raj More
+1  A: 

If you installed SQL Server with the default collation options, you might find that the following queries return the same results:

CREATE TABLE mytable 
( 
    mycolumn VARCHAR(10) 
) 
GO 

SET NOCOUNT ON 

INSERT mytable VALUES('Case') 
GO 

SELECT mycolumn FROM mytable WHERE mycolumn='Case' 
SELECT mycolumn FROM mytable WHERE mycolumn='caSE' 
SELECT mycolumn FROM mytable WHERE mycolumn='case'

You can alter your query by forcing collation at the column level:

SELECT myColumn FROM myTable  
    WHERE myColumn COLLATE Latin1_General_CS_AS = 'caSE' 

SELECT myColumn FROM myTable  
    WHERE myColumn COLLATE Latin1_General_CS_AS = 'case' 

SELECT myColumn FROM myTable  
    WHERE myColumn COLLATE Latin1_General_CS_AS = 'Case' 

-- if myColumn has an index, you will likely benefit by adding 
-- AND myColumn = 'case' 

SELECT DATABASEPROPERTYEX('<database name>', 'Collation')

As changing this setting can impact applications and SQL queries, I would isolate this test first. From SQL Server 2000, you can easily run an ALTER TABLE statement to change the sort order of a specific column, forcing it to be case sensitive. First, execute the following query to determine what you need to change it back to:

EXEC sp_help 'mytable'

The second recordset should contain the following information, in a default scenario:

Column_Name Collation


mycolumn SQL_Latin1_General_CP1_CI_AS

Whatever the 'Collation' column returns, you now know what you need to change it back to after you make the following change, which will force case sensitivity:

ALTER TABLE mytable 
    ALTER COLUMN mycolumn VARCHAR(10) 
    COLLATE Latin1_General_CS_AS 
GO 



SELECT mycolumn FROM mytable WHERE mycolumn='Case' 
SELECT mycolumn FROM mytable WHERE mycolumn='caSE' 
SELECT mycolumn FROM mytable WHERE mycolumn='case'

If this screws things up, you can change it back, simply by issuing a new ALTER TABLE statement (be sure to replace my COLLATE identifier with the one you found previously):

ALTER TABLE mytable 
    ALTER COLUMN mycolumn VARCHAR(10) 
    COLLATE SQL_Latin1_General_CP1_CI_AS

If you are stuck with SQL Server 7.0, you can try this workaround, which might be a little more of a performance hit (you should only get a result for the FIRST match):

SELECT mycolumn FROM mytable WHERE 
    mycolumn = 'case' AND 
    CAST(mycolumn AS VARBINARY(10)) = CAST('Case' AS VARBINARY(10)) 

SELECT mycolumn FROM mytable WHERE 
    mycolumn = 'case' AND 
    CAST(mycolumn AS VARBINARY(10)) = CAST('caSE' AS VARBINARY(10)) 

SELECT mycolumn FROM mytable WHERE 
    mycolumn = 'case' AND 
    CAST(mycolumn AS VARBINARY(10)) = CAST('case' AS VARBINARY(10)) 

-- if myColumn has an index, you will likely benefit by adding 
-- AND myColumn = 'case'
Will Marcouiller