mardi 2 décembre 2008

sp_msForEachTable, la perle cachée

 sp_msForEachTable est une stored procedure non documentée de Microsoft mais néanmoins bien partique.
Cette dernière permet d'exécuter une série de commandes pour chacune des tables utilisateur se trouvant dans une base de donnée.


Executer des commandes
Les commandes à executer sont passées en paramètres dans une chaine de caratère.
Les différentes commandes sont séparées par un point virgule et le point d'interrogation sera substitué avec le nom de la table.

sp_msForEachTable ' DBCC CheckTable( ''?'' ) ; go ;'

A noter que les simple quotes sont doublées dans la chaine de caractères.

Generer du script SQL
Cependant, cet utilitaire à un revers... car il execute les commandes.
Dans notre cas, il y a queqlues tables pour lesquelles nous ne désirons pas exécuter CheckTable.
C'est le cas de notre table d'audit qui nécessite 4h30 de vérification.

Pour contourner ce problème, il faut utiliser sp_msForEachTable pour générer le script de vérification mais non pour l'exécuter.
Le script ainsi généré pour être copier/coller et modifier en fonction des besoins avant sont éxécution.

use myDatabase
go
sp_msforeachtable 'print "print ''---- Check table ? ------------------------''" ; print "DBCC CheckTable(''?'')" ; print "GO" ; print "print '' ''" ; print "print '' ''" '

Les commandes sont imprimées dans l'output à l'aide de l'instruction print.
Cette approche réclame cependant de jongler avec les doubles quotes, et la doublure des simple quotes.
  1. L'argument de l'instruction print (donc les commandes à imprimer) est enfermé dans des doubles quotes
  2. Les parametres texte des commande à imprimer sont enfermés dans des simples quotes doublées
La commande suivante:
sp_msforeachtable 'print "print ''---- Check table ? ------------------------''" ; print "DBCC CheckTable(''?'')" ; print "GO" ; print "print '' ''" ; print "print '' ''" '

Produit le résultat suivant:
print '---- Check table [dbo].[tblWarning] ------------------------'
DBCC CheckTable('[dbo].[tblWarning]')
GO
print ' '
print ' '
print '---- Check table [dbo].[tblHistory] ------------------------'
DBCC CheckTable('[dbo].[tblHistory]')
GO
print ' '
print ' '
print '---- Check table [dbo].[tblForms] ------------------------'
DBCC CheckTable('[dbo].[tblForms]')
GO
print ' '
print ' '
...

Aucun commentaire: