SET RECOVERY Модель с использованием sp_msforeachdb

Я хотел создать сценарий, который устанавливает РЕЖИМ ВОССТАНОВЛЕНИЯ для каждой пользовательской базы данных на ПРОСТОЙ и поместить его в задание агента для моих серверов разработки. Это казалось простым (извините за каламбур)

EXEC sp_msforeachdb 'USE ?; IF DB_ID() >= 5 ALTER DATABASE ? SET RECOVERY SIMPLE;'

Это тоже работает. Только выполнение против правильных баз данных, и все такое. Тем не менее, я получаю следующее сообщение об ошибке:

Сообщение 5058, уровень 16, состояние 1, строка 1
Опция 'RECOVERY' не может быть установлена ​​в базе данных 'tempdb'.

Я мог бы написать динамический SQL с представлением sys.databases для пользовательских баз данных, но мне интересно, почему sp_msforeachdb генерирует эту ошибку.

У кого-нибудь есть опыт, который мог бы пролить свет на это?

РЕДАКТИРОВАТЬ: С кодом, установленным для исключения любой БД с идентификатором < 5, я озадачен, почему я вообще получаю эту ошибку.

4 ответа

Решение

Вы должны использовать динамический SQL для реализации этого, потому что DDL оценивается для каждой базы данных независимо от проверки, но не выполняется из-за проверки.

set quoted_identifier on

EXEC sp_msforeachdb "
IF '?' not in ('tempdb')
begin
    exec ('ALTER DATABASE [?] SET RECOVERY SIMPLE;')
    print '?'
end
"

Вы получаете эту ошибку, потому что DB_ID() оценивает "текущую" базу данных. Таким образом, если вы выполнили свою инструкцию sp_msforeachdb в master, db_id() всегда будет иметь значение 1, а условное выражение всегда будет иметь значение true. Я подозреваю, что вы хотите что-то вроде этого:

EXEC sp_msforeachdb 'IF DB_ID(''?'') >= 5 ALTER DATABASE [?] SET RECOVERY SIMPLE;'

Согласно документации: "Резервное копирование и восстановление не разрешены на TempDB".

Это потому, что он предназначен только для временного хранения (резервные копии и временные не идут вместе). Поэтому, если вам нужно подтвердить это, вы делаете что-то не так. Другими словами, Microsoft пытается предотвратить ошибки.

Справочная документация, которая включает другие ограничения базы данных tempdb: http://msdn.microsoft.com/en-us/library/ms190768.aspx

EXEC sp_MSforeachdb N'IF DatabasePropertyEx(''?'', ''Recovery'')=''FULL''
    and   DatabasePropertyEx(''?'', ''Status'')=''ONLINE'' 
    and ''?'' not in (''tempdb'')
begin
  exec (''ALTER DATABASE [?] SET RECOVERY SIMPLE;'')
  print ''?''
end' 
Другие вопросы по тегам