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
).
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
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
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