如何防止在SQL语法中影响表名的排序规则?

时间:2017-11-14 18:04:33

标签: sql sql-server tsql collation

有人可以解释如何保护表名不受整理设置的影响吗? 我目前收到错误消息:

(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'.

从这个SQL:

USE master;  
CREATE DATABASE MyDatabase COLLATE Danish_Norwegian_CI_AS;
GO

USE MyDatabase
CREATE TABLE DataArchive (id INT);
GO

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

USE MASTER;
DROP DATABASE MyDatabase;
GO

我希望整理应用于排序我的数据,而不是表名本身。

背景

出现这种情况是因为客户负责安装SQL Server,并将服务器排序规则设置为Danish_Norwegian_CI_AS,因此默认情况下任何数据库都具有此排序规则(我们在创建数据库时并未专门设置数据库的排序规则新数据库通过代码/脚本)。在这种情况下,我仍然没有想到我们的表名将被完全不同地解释。这意味着我们唯一的选择是在数据库上强制拉丁校对,如果用户想要不同的东西,用户可以指定每列校对吗?

1 个答案:

答案 0 :(得分:2)

我认为SQL Server在执行查询,检查或编译之前,例如它检查表验证如下:

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

那没有结果。而是用于返回结果的其他模式 因此,它会提高:

  

无效的对象名称'Dataarchive'。

但您可以使用其他sys.object来查看COLLATION

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

这将产生一个结果,AFAIK,你不能强迫SQL Server DBMS像这样进行检查或编译。

顺便说一句,在这种情况下,您可以使用动态SQL获取表的数据 - 如下所示:

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;