Home How to prevent collation affecting table names in SQL syntax?
Reply: 1

How to prevent collation affecting table names in SQL syntax?

GilesDMiddleton Published in 2017-11-14 18:04:33Z

Can someone explain how to protect table names from being subject to the collation settings? I'm currently getting the error message:

(0 row(s) affected)

(0 row(s) affected)

(0 row(s) affected)
Msg 208, Level 16, State 1, Line 1
Invalid object name 'Dataarchive'.
Msg 208, Level 16, State 1, Line 1
Invalid object name 'MyDatabase.dbo.Dataarchive'.

From this SQL:

USE master;  
CREATE DATABASE MyDatabase COLLATE Danish_Norwegian_CI_AS;

USE MyDatabase
CREATE TABLE DataArchive (id INT);

SELECT * FROM DataArchive; -- succeeds
SELECT * FROM dataArcHIVE; -- succeeds
SELECT * FROM [MyDatabase].[dbo].[DataArchive]; -- succeeds
SELECT * FROM Dataarchive; -- fails - interprets aa as special A character.
SELECT * FROM [MyDatabase].[dbo].[Dataarchive]; -- fails


I expected collation to apply to sorting my data, not to table names themselves.


This situation has arisen because the customer was responsible for installing the SQL Server, and set the server collation to Danish_Norwegian_CI_AS, thus any database, by default has this collation (and we do not specifically set the collation of the Database when creating a new database through code/script). In this situation, I still did not expect that our table names would be interpreted differently at all. Meaning our only option is to force latin collation on the database and users can specify per-column collation if they want something different?

shA.t Reply to 2017-11-15 09:31:06Z

I think SQL Server before execute a query, check or compile it, for example it checks for table validation like this:

select *
from sys.objects
where name = N'Dataarchive'

That will have no result. instead for other modes that will return a result.
Because of this it will raise:

Invalid object name 'Dataarchive'.

But you can check over sys.object with another COLLATION like this:

select *
from sys.objects
where name COLLATE latin1_General_CI_AI = N'Dataarchive'

That will have a result, AFAIK, You can't force SQL Server DBMS to do its check or compile like this.

BTW, You can get data of a table in that case - with using Dynamic SQL - like this:

declare @tablename nvarchar(255) = 'Dataarchive';
declare @sql nvarchar(255) = 
    N'SELECT * FROM '+ (
        select name 
        from sys.tables 
        where name = @tablename COLLATE Latin1_General_CI_AI);
exec sp_sqlexec @sql;
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.34744 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO