SQL Server 版本(从选择 @@VERSION 输出):Microsoft SQL Server 2017 (RTM-CU19) (KB4535007) - 14.0.3281.6 (X64) (Build 14393: )
sp_Blitz
从 Brent Ozar安装,存储过程创建成功。
代码中的版本信息:SELECT @Version = '7.93', @VersionDate = '20200217';
该实例有 4 个带排序规则的系统SQL_Latin1_General_CP1_CI_AS
数据库和 2 个带排序规则的用户数据库SQL_Latin1_General_CP1_CS_AS
当我尝试运行时,sp_Blitz
我得到了这个:
消息 468,级别 16,状态 9,过程 sp_Blitz,第 896 行 [批处理开始行 0] 无法解决等于操作中“SQL_Latin1_General_CP1_CS_AS”和“SQL_Latin1_General_CP1_CI_AS”之间的排序规则冲突。
感谢您在故障排除方面的任何帮助(我主要是一个 Oracle 人员,他收到了一个 SQL Server 进行审查,并记住这可能是一个很好的开始,对于显而易见的事情开始)。
从评论中添加解决方案:存储过程是在区分大小写的用户数据库中创建的,它试图将内容复制到区分大小写的 TempDB 中。
从区分大小写的用户数据库中删除 sp_Blitz 并将其安装在 master 中(然后将反映系统数据库排序规则)后,它工作正常。
不要质疑供应商推荐的用法,但据我所知,在“典型”条件下,sp_Blitz安装在用户数据库中时工作得很好,即使是与实例具有不同排序规则的数据库。什么不是“典型的”,以至于会出现排序规则不匹配错误?使用包含的数据库(即“
CONTAINMENT = PARTIAL
”)。发生错误是因为在包含的数据库中,[tempdb]
用户数据(与[tempdb]
元数据相反)的默认排序规则实际上是包含的数据库的默认排序规则(类似于表变量的工作方式)。在“典型”条件下,sp_Blitz中的许多查询包含以下
WHERE
谓词(d
表别名为 forsys.databases
):工作得很好,即使这个存储过程是使用不同于实例级排序规则的默认排序规则在数据库中创建的,因为
sys.databases.name
使用实例级排序规则,并且#SkipChecks.DatabaseName
(因为语句中没有COLLATE
子句CREATE TABLE
)使用默认排序规则of[tempdb]
,其中 99.999% 的时间也是实例级排序规则。重现 OP 收到的错误的唯一方法是执行以下操作:
假设用户 DB 的排序规则与实例不同(因此与 不同),那么在执行sp_Blitz
[tempdb]
时会出现以下错误:同样,如果供应商(即 Brent)说此存储过程旨在安装在 中
[master]
,那么最好遵循建议。我只是在解释实际发生的事情,因为它是不明显的行为。此外,这是另一个真正受益于特殊排序规则名称的情况,该名称将动态替换为实例级排序规则。到目前为止,
DATABASE_DEFAULT
这是数据库的排序规则,无论该排序规则是什么,都有CATALOG_DEFAULT
旨在帮助包含数据库的排序规则(尽管在这种情况下它无济于事),但没有任何东西代表实例级别。通用脚本,例如sp_Blitz、Ola Hallengren 的数据库维护脚本等,旨在对整个实例进行操作,并没有针对特定系统进行编码,将不可避免地遇到这个问题,并且必须做出不必要的让步才能使其正常工作。所以,请投票支持我的以下建议来解决这种情况:添加特殊排序规则 INSTANCE_DEFAULT 以像 COLLATE DATABASE_DEFAULT 一样工作,但使用实例的默认排序规则
如果可以使用创建临时表
[DatabaseName] sysname COLLATE INSTANCE_DEFAULT
,那么此代码将始终有效,无论放置什么数据库,是否包含等等。它会正常工作。