You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

SQL Server查询sys.database_permissions时出现Invalid Object Name错误求助

分析你的sys.database_permissions查询报错问题

你遇到的这种“先返回部分结果,随后抛出Invalid Object Name错误”的情况,结合你用sp_MSForEachdb遍历所有数据库的场景,大概率是以下几个原因之一:

1. 存在状态异常的数据库

sp_MSForEachdb会尝试遍历所有数据库(包括系统库),如果某个数据库处于以下状态,访问它的sys.database_permissions就会报错:

  • 脱机(Offline)状态
  • 还原中(Restoring)状态
  • 可疑(Suspect)状态
  • 只读(Read-Only)状态且当前会话没有足够的访问权限(虽然你说权限没问题,但可以再确认下这类库的权限)

比如当脚本执行到一个脱机的数据库时,[?].sys.database_permissions就会因为数据库无法访问而抛出对象不存在的错误。

2. sp_MSForEachdb的已知缺陷

这个存储过程是微软未正式公开的工具,存在不少小问题:

  • 特殊数据库名称处理错误:如果你的数据库名称包含中括号(比如My[DB]),[?]替换后会变成[My[DB]],这会导致SQL语法错误,触发对象不存在的报错。
  • 跳过某些库的逻辑不稳定:它偶尔会错误地尝试访问一些本应跳过的系统库(比如resource数据库,这个库是隐藏的,直接访问会报错)。

3. 系统视图依赖的底层系统表损坏

sys.database_permissions是基于系统表(比如sys.syspermissionssys.sysusers等)构建的视图,如果某个数据库的这些底层系统表存在损坏(比如页错误、无效条目),查询视图时就会抛出异常。这种情况通常伴随其他数据库异常,比如DBCC检查会报错。

4. 数据库兼容性级别过低

如果某个数据库的兼容性级别设置为SQL Server 2000(级别80)或更低,虽然sys.database_permissions视图在高版本SQL Server中依然存在,但低兼容性级别下视图的查询逻辑可能出现冲突,导致报错。

排查建议

你可以先修改脚本,添加错误捕获和数据库状态检查,定位到具体出问题的数据库:

EXEC sp_MSForEachdb '
BEGIN TRY
    IF DATABASEPROPERTYEX(''?'', ''Status'') = ''ONLINE''
    BEGIN
        SELECT distinct p.permission_name , ''?'' AS DatabaseName 
        FROM [?].sys.database_permissions p
    END
END TRY
BEGIN CATCH
    SELECT ''Error accessing database: '' + ''?'' AS ErrorInfo, ERROR_MESSAGE() AS ErrorDetails
END CATCH
'

这个脚本会跳过离线数据库,并捕获报错的库和具体错误信息,帮你精准定位问题根源。

内容的提问来源于stack exchange,提问作者Vaseem Akram

火山引擎 最新活动