在我的一个应用程序中,我们有如下所示的tsql
SELECT DISTINCT [Dblist].[DbName] AS [DbName]
FROM [Common].dbo.[Dblist]
WHERE dbname not in (
SELECT [name]
FROM master.dbo.sysdatabases )
对于我的一个客户,它给出了一个与排序规则相关的错误,因为数据库Common
(我的应用程序的一部分)具有默认排序规则sql_latin1_general_cp1_ci_as
,而主db具有排序规则latin1_general_ci_as
。我找到了一种使用校对的解决方案,它起了作用。我要解决所有的校对工作。
SELECT DISTINCT [Dblist].[DbName] AS [DbName]
FROM [Common].dbo.[Dblist]
WHERE dbname not in (
SELECT [name] COLLATE DATABASE_DEFAULT
FROM master.dbo.sysdatabases )
现在我很困惑。我应该在所有涉及系统数据库的查询中使用排序规则吗?什么时候使用校对,什么时候不用?
另外,上面使用排序规则的方法是否正确(比如排序规则DATABASE_DEFAULT)?这里,DATABASE_DEFAULT是latin1_general_ci_as本身,因为它是主数据库的排序规则。那么,该解决方案是如何工作的,因为它们再次与公共数据库不匹配?我想要的解决方案将在所有的校对工作。
发布于 2014-10-15 12:12:35
如果要对特定数据库使用自定义排序规则,则需要在加入或联合两个数据库的数据时使排序规则匹配。
实际上,无论如何,您将需要使用许多元数据查询来完成这一任务。只需查看像sys.tables
这样的目录视图:
SELECT c.name, c.collation_name
FROM sys.all_columns AS c
INNER JOIN sys.all_views AS v
ON c.[object_id] = v.[object_id]
INNER JOIN sys.schemas AS s
ON v.[schema_id] = s.[schema_id]
WHERE s.name = N'sys' AND v.name = N'tables'
AND c.collation_name IS NOT NULL;
结果:
name SQL_Latin1_General_CP1_CI_AS
type Latin1_General_CI_AS_KS_WS
type_desc Latin1_General_CI_AS_KS_WS
lock_escalation_desc Latin1_General_CI_AS_KS_WS
durability_desc Latin1_General_CI_AS_KS_WS
因此,我们在一个系统对象中有两个不同排序规则的列。任何数据库都不能有匹配两者的DATABASE_DEFAULT
.
您无法控制客户列或数据库的排序规则或服务器排序规则。因此,解决冲突的唯一办法就是:
DATABASE_DEFAULT
)因为后者是更多的工作,使查询更加复杂,并带来更多的机会将搜索转化为扫描,我认为前者确实是您的最佳选择。
发布于 2014-10-15 11:33:45
来自网上图书
database_default -使排序规则子句继承当前数据库的排序规则。
如果您正在从common
数据库执行第二个查询,那么来自master.dbo.sysdatabases
的值将被胁迫到common
的S排序规则中,而不是像您想象的那样反过来。
https://dba.stackexchange.com/questions/80220
复制相似问题