Назад | Перейти на главную страницу

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

Обе 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 не перечисляет их.

Зачем?
С чего мне начать узнавать?

редактировать: Окружающая среда

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 для всех.
Со списком найденных кодов состояния Вот и определение sp_msforeachdb, Я сделал это так, что исключает status как проблема:

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

Таким образом, последние 4 базы данных из списка имеют «неверный логин».
Пора заняться безопасностью и правами ...

- Джерун

Решено! В 0x4000000 бит состояния базы данных - это AutoClose установка БД.
AutoClose это плохо, не только потому, что сбивает с толку ms_foreachdb, но и потому, что часто снижает вашу производительность. Хорошие новости: он в «списке убийств».

sp_helpdb может анализировать статусы в удобочитаемой форме и показывает, что 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

Отключить AutoClose очень просто:

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

- Джерун

ms_foreachdb не работает так же хорошо в SQL Server 2005 или новее, но если вы скопируете логику из этой хранимой процедуры и измените тип курсора на INSENSITIVE, эта недокументированная хранимая процедура будет работать правильно. Однако лучше всего будет использовать свой собственный код для проверки в будущем.

SQL Server Management Studio выполняет запрос к представлению каталога sys.databases. Все базы данных перечислены в этом DMV. Хранимая процедура sp_msforeachdb имеет логику, которая вызывает функцию has_dbaccess () для анализа своего списка баз данных. Очевидно, он не хочет пытаться запустить команду для базы данных, к которой у вас нет доступа. Есть ли у вас доступ ко всем рассматриваемым базам данных с учетной записью, использованной для выполнения запроса?