Gil*_*ton 5 sql t-sql sql-server 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'.
Run Code Online (Sandbox Code Playgroud)
从这个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
Run Code Online (Sandbox Code Playgroud)
我希望整理适用于排序我的数据,而不是表名本身.
背景
出现这种情况是因为客户负责安装SQL Server,并将服务器排序规则设置为Danish_Norwegian_CI_AS,因此默认情况下任何数据库都具有此排序规则(并且我们不会在通过以下方式创建新数据库时专门设置数据库的排序规则代码/脚本).在这种情况下,我仍然没有想到我们的表名将被解释为完全不同.这意味着我们唯一的选择是在数据库上强制拉丁校对,如果用户想要不同的东西,用户可以指定每列校对吗?
我认为 SQL Server 在执行查询之前,检查或编译它,例如它检查表验证,如下所示:
select *
from sys.objects
where name = N'Dataarchive'
Run Code Online (Sandbox Code Playgroud)
那不会有结果。而对于其他将返回结果的模式。
因此,它会引发:
对象名称“Dataarchive”无效。
但你可以像这样检查sys.object另一个COLLATION:
select *
from sys.objects
where name COLLATE latin1_General_CI_AI = N'Dataarchive'
Run Code Online (Sandbox Code Playgroud)
这将会产生一个结果,据我所知,您不能强制 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;
Run Code Online (Sandbox Code Playgroud)