2 votes

Modèle SET RECOVERY utilisant sp_msforeachdb

Je voulais construire un script qui définit le MODE DE RÉCUPÉRATION pour chaque base de données utilisateur à SIMPLE et le mettre dans un travail d'agent pour mes serveurs de développement. Cela semblait simple (désolé pour le jeu de mots) :

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

Cela fonctionne aussi. Il s'exécute uniquement sur les bonnes bases de données, et tout ça. Cependant, j'obtiens le message d'erreur suivant :

Msg 5058, Niveau 16, État 1, Ligne 1
L'option 'RECOVERY' ne peut pas être définie dans la base de données 'tempdb'.

Je pourrais écrire du SQL dynamique dans la vue sys.databases pour les bases de données utilisateur, mais je me demande pourquoi sp_msforeachdb génère cette erreur.

Quelqu'un a-t-il une expérience qui pourrait l'éclairer ?

EDIT : Avec le code défini pour exclure tout DB avec un ID < 5, je suis perplexe quant à la raison pour laquelle j'obtiens cette erreur.

6voto

Jason Cumberland Points 1559

Vous devez utiliser le SQL dynamique pour mettre en œuvre cette méthode, car la DDL est évaluée pour chaque base de données indépendamment de la vérification, mais elle n'est pas exécutée à cause de la vérification.

set quoted_identifier on

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

0voto

Kyle Brandt Points 81077

Selon la documentation : "Les sauvegardes et restaurations ne sont pas autorisées sur TempDB".

En effet, il n'est destiné qu'à un stockage temporaire (les sauvegardes et le temporaire ne vont pas ensemble). Donc si vous avez besoin de le sauvegarder, vous faites quelque chose de mal. En d'autres termes, Microsoft essaie d'éviter les erreurs.

Documentation de référence qui inclut d'autres limites de tempdb : http://msdn.microsoft.com/en-us/library/ms190768.aspx

0voto

Ben Thul Points 2939

Vous obtenez cette erreur parce que DB_ID() évalue la base de données "actuelle". Donc, si vous exécutez votre instruction sp_msforeachdb dans master, db_id() sera toujours évalué à 1 et donc la conditionnelle sera toujours évaluée à true. Je pense que vous voulez quelque chose comme ceci :

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

-3voto

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'

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X