Affichage des articles dont le libellé est Bases. Afficher tous les articles
Affichage des articles dont le libellé est Bases. Afficher tous les articles

05 octobre 2013

SQL : Connaitre la liste des bases d'un serveur

Pour connaitre simplement la liste des bases disponibles sur une instance d'un serveur SQL Server :

Ma première approche fut :

SELECT name FROM sys.databases ORDER BY name

Ouai bof

Maintenant je préfère Plus simple, et semble t il plus perein :

EXEC sp_databases

A noter que ces 2 requêtes fonctionnent quelque soit la base sur laquelle on les exécutes.

sp_database nécessite l'autorisation "CREATE DB" ou équivalent et il faut s'assurer que "VIEW ANY DEFINITION" n'est pas refusé.

29 septembre 2013

SQL : Exécuter une requête sur toutes les bases d'un serveur

Exécuter une même requête SQL Server sur quelques (ou toutes les) tables d'un serveur ?

La procédure sp_msforeachdb (non documentée) peut aider :

EXEC sp_msforeachdb '
USE [?]; 
IF (''?'' LIKE ''m%'' AND EXISTS (SELECT 1 FROM sys.tables WHERE name = ''object''))
BEGIN 
 Print ''?'' + '' as not object''
END;

'

L'argument chaîne se décompose en :

  • USE ==> pour basculer sur la base.  ? est le nom de la base en cours. Notez les [] qui encadrent le ?
  • IF ==> 
           1) tester la ou les bases qui nous intéressent (pourrait être fait avant le use) 
           2) tester s'il y a ce qu'il faut dans la base pour que la requête fonctionne
  • Entre le BEGIN et le END ==> la requête à exécuter.
On peut aussi créer une table temporaire avant l'exécution de cette requête et y agréger les résultat par un insert au lieu d'un sélect. On obtient ainsi une seule table de données :

CREATE TABLE #tmp (base VARCHAR(50) NOT NULL, nombre INT NOT NULL);

EXEC sp_msforeachdb '
Use [?]; 
IF (''?'' LIKE ''m%'' AND EXISTS (SELECT 1 FROM sys.tables WHERE name = ''object''))
BEGIN 
 INSERT INTO #tmp (base, nombre) SELECT ''?'' AS base, COUNT(*) FROM sys.tables
END;
'
SELECT * FROM #tmp;


Attention selon les colonnes présente ou pas dans la base certaine requête pourraient planter. 
Pour contourner ce problème voici un exemple :

EXEC sp_msforeachdb '
USE [?]; 
IF (''?'' LIKE ''mes_bases_%'' AND EXISTS (SELECT 1 FROM sys.tables t INNER JOIN sys.columns c ON t.object_id = c.object_id WHERE t.name = ''table1'' AND c.name = ''colonne_qui_est_pas_dans_toutes_les_bases'')  )
BEGIN 
   Declare @msg varchar(max)
   SET @msg = ''SELECT ''''?'''' as base, count(*) as nombre FROM table1 WHERE colonne_qui_est_pas_dans_toutes_les_bases is not null'';
   EXEC (@msg);
END;
'

Comptez bien le nombre d'apostrophes !!!!



Enjoy;