我正在使用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
BOON0205和KAB205都已经用这样的命令恢复:
%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?
编辑 :环境
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