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'