sp_msforeachdb不会列出SQL Server实例上的所有数据库

我正在使用sp_msforeachdb列出我的服务器上的所有数据库
我知道这是不受支持的 ,但我想知道为什么它没有列出我已经安装的所有数据库。

这是我如何运行它:

 set run="C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE" -S .\SQL2008 -E -h -1 -Q %run% "exec sp_msforeachdb 'select ''?'''" 

输出:

 master tempdb model msdb balance166 

SSMS显示的数据库:

 master tempdb model msdb balance166 BOON205 KAB205 

BOON0205KAB205都已经用这样的命令恢复:
%run% "..."其中"..."是这样的语句在一行上:

 RESTORE DATABASE [BOON205] FROM DISK = N'C:\Data\Backup\Balance205.bak' WITH REPLACE, STATS = 10, MOVE N'Balance166' to N'C:\Data\Balance205.mdf', MOVE N'Balance166_log' to N'C:\Data\Balance205_log.ldf'; 

还原显然有效:我可以很好地连接到这些数据库。
但是sp_msforeachdb不会列出它们。

为什么?
我在哪里可以find?

编辑 :环境

  • SQL Server 2008版本10.0.1600.22 RTM标准版
  • Windows Server 2008 Standard
  • login的用户是在一个域中,但在本机上的本地pipe理员,并作为Windows用户添加到SQL Server数据库安全性与“授予控制服务器”

sys.databases是好的:

 C:\bin>%sqlrun% -Q "select name from sys.databases" name ----------------------------------------------------------------------------- master tempdb model msdb balance166 Balance205 KAB205 BOON205 (8 rows affected) 

has_dbaccess是好的,但status可能不是。 需要检查出来:

 C:\bin>%sqlrun% -Q "select cast(name as varchar(10)), status, cast(status as varbinary(8)), DATABASEPROPERTY(name, 'issingleuser') as issingleuser, has_dbaccess(name) as has_dbaccess from master.dbo.sysdatabases" status issingleuser has_dbaccess ---------- ----------- ---------- ------------ ------------ master 65544 0x00010008 0 1 tempdb 65544 0x00010008 0 1 model 65536 0x00010000 0 1 msdb 65544 0x00010008 0 1 balance166 65536 0x00010000 0 1 Balance205 1073807361 0x40010001 0 1 KAB205 1073807361 0x40010001 0 1 BOON205 1073807361 0x40010001 0 1 

这不是状态,因为DATABASEPROPERTYEX('master', 'Status')对于它们都返回ONLINE DATABASEPROPERTYEX('master', 'Status')
有了这里发现的状态代码列表和sp_msforeachdb的定义 ,我将其视为一个问题:

  8 0x00000008 - 'trunc. log on chkpt' 65536 0x00010000 - 'online' 65544 0x00010008 - 65536 + 8 1073741824 0x40000000 - 'invalid login' 1073807361 0x40010001 - 1073741824 + 65536 + 8 

因此,列表中的最后4个数据库有“无效login”。
有时间研究安全和权利

–jeroen

SQL Server Management Studio对sys.databases目录视图执行查询。 所有数据库都在DMV中列出。 存储过程sp_msforeachdb具有调用函数has_dbaccess()来parsing其数据库列表的逻辑。 它显然不想尝试针对没有访问权限的数据库运行命令。 您是否有权使用用于运行查询的帐户访问所有有问题的数据库?

ms_foreachdb在SQL Server 2005或更高版本中无法正常工作 – 但是,如果您从此存储过程中复制出逻辑,并将游标types更改为INSENSITIVE,则这个未logging的存储过程确实可以正常工作。 但是,您最好将自己的代码用于将来的打样。

解决了! 数据库状态的0x4000000位是DB的AutoClose设置。
AutoClose是不好的,不仅因为它混淆了ms_foreachdb,而且因为它经常会使你的性能变差。 好消息:这是在“杀人名单”上。

sp_helpdb可以将状态分解为可读forms,并显示sp_msforeachdb 源代码错误地将AutoClose标志解释为InvalidLogin 🙂

这就是sp_helpdb显示的内容(向右滚动以查看Balance166和Balance205之间的差异):

 Balance166 Status=ONLINE, Updateability=READ_WRITE, UserAccess=MULTI_USER, Recovery=FULL, Version=655, Collation=SQL_Latin1_General_CP1_CI_AS, SQLSortOrder=52, IsAutoCreateStatistics, IsAutoUpdateStatistics Balance205 Status=ONLINE, Updateability=READ_WRITE, UserAccess=MULTI_USER, Recovery=FULL, Version=655, Collation=SQL_Latin1_General_CP1_CI_AS, SQLSortOrder=52, IsAutoClose, IsAutoCreateStatistics, IsAutoUpdateStatistics 

closuresAutoClose很简单:

 USE [master] GO ALTER DATABASE [Balance205] SET AUTO_CLOSE OFF WITH NO_WAIT GO 

并导致这些设置:

 name status Xstatus DBStatus issingleuser has_dbaccess ---------- ------- ---------- ---------- ------------ ------------ Balance166 65536 0x00010000 ONLINE 0 1 Balance205 65536 0x00010000 ONLINE 0 1 

–jeroen