2010-10-01 7 views
0

Je travaille avec beaucoup de bases de données identiques. J'utilise donc la procédure sp_MSforeachdb pour récupérer des informations dans une table.sp_MSforeachdb aide à la requête

Le problème que j'ai rencontré est qu'il y a d'autres bases de données sur la boîte qui n'ont pas la table, donc je jette des erreurs d'objet invalides.

Voici ce que j'ai pour le moment, je filtre LoginDatabase car il a la même table mais je ne le veux pas dans la requête.

Ma question est, comment puis-je restreindre juste aux bases de données avec la table dont je veux récupérer des informations.

SET NOCOUNT ON 

CREATE TABLE #tmpData 
(
    DbName VARCHAR(30), 
    DbVersion FLOAT 
) 

exec sp_msforeachdb @command1=' 
    USE ?; 

    INSERT INTO #tmpData 
    SELECT ''?'', (SELECT Setting 
     FROM ?.dbo.gl_SysParams 
     WHERE Keyword = ''DatabaseSchema'') 
    FROM sysobjects o 
    WHERE type=''U'' 
    AND [name] = ''gl_SysParams'' 
    AND ''?'' <> ''LoginDatabase'' ORDER BY [name] 
    ' 

SET NOCOUNT OFF 

SELECT DbName, DbVersion FROM #tmpData ORDER BY DbName 

DROP TABLE #tmpData 

Répondre

2

Vous pouvez utiliser un appel à sp_MSforeachtable dans chaque base de données, où vous utilisez le paramètre @WhereAnd pour filtrer vers le bas juste la table qui vous intéresse - il ne sera pas exister dans la base de données que vous n'êtes pas intéressé par, donc sp_MSforeachtable s'exécutera 0 fois là-bas, et 1 fois dans chaque base de données avec la table.

Modifier Exemple simple il suffit d'exécuter sur un serveur aléatoire de moi, où je savais qu'une seule base de données avait une table de tblClient, avec une colonne de ClientID (pardonnez la dénomination):

create table #t (
    ID int not null 
) 
exec sp_MSforeachdb 'use ? exec sp_MSforeachtable ''insert into #t(ID) select ClientID from ~'',''~'',@whereand=''and o.name=''''tblClient''''''','?' 
select * from #t 
drop table #t 
+0

Alors enveloppez sp_MSforeachtable dans la commande @ de sp_MSforeachdb? –

+0

@Sres - oui. Les citations peuvent être un peu déroutantes, et bien sûr, vous devez spécifier le @replacechar pour l'un des processus stockés –

+0

Je rencontre un problème avec le nom de la colonne Ambiguous 'name' maintenant, j'ai alias les sysobjects de l'original ci-dessus, quelle est la table @whereand looking? –

0

Solution avec l'aide de Damien_the_Unbeliever

SET NOCOUNT ON 

CREATE TABLE #tmpData 
(
    DbName VARCHAR(30), 
    DbVersion FLOAT 
) 

exec sp_MSforeachdb @command1 = ' 
    USE ?; 

    exec sp_MSforeachtable @command1 = ''INSERT INTO #tmpData 
    SELECT ''''?'''', (SELECT Setting 
     FROM ?.dbo.gl_SysParams 
     WHERE Keyword = ''''DatabaseSchema'''') 
    FROM sysobjects p 
    WHERE type=''''U'''' 
    AND p.[name] = ''''gl_SysParams'''' 
    AND ''''?'''' <> ''''LoginDatabase'''' ORDER BY [name] 
    '', 
    @whereand = ''AND o.[name] = ''''gl_SysParams'''''' 
    ' 

SET NOCOUNT OFF 

SELECT DbName, DbVersion FROM #tmpData ORDER BY DbName 

DROP TABLE #tmpData