在我的一个应用程序中,我们有如下所示的 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
,而主数据库具有排序规则latin1_general_ci_as
。我找到了一个使用 collate 的解决方案并且它有效。我希望解决方案适用于所有排序规则。
SELECT DISTINCT [Dblist].[DbName] AS [DbName]
FROM [Common].dbo.[Dblist]
WHERE dbname not in (
SELECT [name] COLLATE DATABASE_DEFAULT
FROM master.dbo.sysdatabases )
现在我很困惑。我应该在涉及系统数据库的所有查询中使用 COLLATE 吗?什么时候使用collate,什么时候不使用?
此外,上述使用整理的方式是否正确(如 COLLATE DATABASE_DEFAULT)?这里 DATABASE_DEFAULT 是 latin1_general_ci_as 本身,因为它是主数据库的排序规则。那么解决方案是如何工作的,因为它们再次与通用数据库不匹配?我想要适用于所有排序规则的解决方案。
如果您要对特定数据库使用自定义排序规则,那么是的,每当您加入或合并来自两个数据库的数据时,您都需要使排序规则匹配。
事实上,无论如何您都需要对许多元数据查询执行此操作。只需查看目录视图,例如
sys.tables
:结果:
所以这里我们在单个系统对象中有两个不同排序规则的列。没有数据库可以
DATABASE_DEFAULT
同时匹配两者...您无法控制客户列或数据库的排序规则,或者服务器排序规则。所以真正解决冲突的唯一方法是:
DATABASE_DEFAULT
)由于后者工作量更大,查询更复杂,并引入了更多将搜索转化为扫描的机会,我认为前者确实是您的最佳选择。
来自在线书籍
如果您正在从
common
数据库执行第二个查询,那么 from 的值master.dbo.sysdatabases
将被强制转换为common
' 排序规则,而不是您想象的相反。