web-dev-qa-db-fra.com

Comment exécuter la même requête sur toutes les bases de données d'une instance?

J'ai (à des fins de test) de nombreux dbs avec le même schéma (= mêmes tables et colonnes essentiellement) sur une instance de SQL Server 2008 R2.

je voudrais une requête comme

SELECT COUNT(*) FROM CUSTOMERS

sur toutes les bases de données de l'instance. Je voudrais avoir comme résultat 2 colonnes:

1 - le nom de la base de données

2 - la valeur de COUNT(*)

Exemple:

DBName  //   COUNT (*)

TestDB1 // 4

MyDB  // 5

etc...

Remarque: je suppose que la table CUSTOMERS existe dans tous les dbs (sauf master).

33
LaBracca

Essaye celui-là -

SET NOCOUNT ON;

IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
   DROP TABLE #temp

CREATE TABLE #temp
(
      [COUNT] INT
    , DB VARCHAR(50)
)

DECLARE @TableName NVARCHAR(50) 
SELECT @TableName = '[dbo].[CUSTOMERS]'

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = STUFF((
    SELECT CHAR(13) + 'SELECT ''' + name + ''', COUNT(1) FROM [' + name + '].' + @TableName
    FROM sys.databases 
    WHERE OBJECT_ID('[' + name + ']' + '.' + @TableName) IS NOT NULL
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

INSERT INTO #temp (DB, [COUNT])              
EXEC sys.sp_executesql @SQL

SELECT * 
FROM #temp t

Sortie (par exemple, dans AdventureWorks) -

COUNT       DB
----------- --------------------------------------------------
19972       AdventureWorks2008R2
19975       AdventureWorks2012
19472       AdventureWorks2008R2_Live
42
Devart

Requête simple

EXECUTE sp_MSForEachDB 
        'USE ?; SELECT DB_NAME()AS DBName, 
        COUNT(1)AS [Count] FROM CUSTOMERS'

Cette requête vous montrera ce que vous voulez voir, mais générera également des erreurs pour chaque base de données sans table appelée "CLIENTS". Vous devrez élaborer une logique pour gérer cela.

Raj

32
Raj

Que diriez-vous quelque chose comme ça:

DECLARE c_db_names CURSOR FOR
SELECT name 
FROM sys.databases
WHERE name NOT IN('master', 'tempdb') --might need to exclude more dbs

OPEN c_db_names

FETCH c_db_names INTO @db_name

WHILE @@Fetch_Status = 0
BEGIN
  EXEC('
    INSERT INTO #report
    SELECT 
      ''' + @db_name + '''
      ,COUNT(*)
    FROM ' + @db_name + '..linkfile
  ')
  FETCH c_db_names INTO @db_name
END

CLOSE c_db_names
DEALLOCATE c_db_names

SELECT * FROM #report
8
Dave Sexton