2013-08-27 69 views
24

我有(用於測試目的)在sql server 2008 r2實例上具有相同模式(=基本上相同的表和列)的許多dbs。如何在實例上的所有數據庫上運行相同的查詢?

我想喜歡

SELECT COUNT(*) FROM CUSTOMERS 

上的實例中的所有數據塊的查詢。我想有作爲的結果2列:

1 - 數據庫名稱

2 - COUNT(*)

例中的價值:

DBName // COUNT (*) 

TestDB1 // 4 

MyDB // 5 

etc... 

注意:CUSTOMERS表存在我承擔在所有dbs中(master除外)。

回答

31

嘗試這一個 -

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 

輸出(例如,在AdventureWorks) -

COUNT  DB 
----------- -------------------------------------------------- 
19972  AdventureWorks2008R2 
19975  AdventureWorks2012 
19472  AdventureWorks2008R2_Live 
+0

嗨Devart,我使用這個SQL和偉大的工程。但是,如果運行此查詢的用戶能否訪問每個數據庫,是否可以添加檢查,如果不是,則查詢仍應繼續運行,並只返回用戶有權訪問的數據庫。我所追求的是用戶是否對每個數據庫擁有DBO角色權限,如果不移動到下一個數據庫上,請您提供建議。 – DK2014

23

直截了當查詢

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

這個查詢會告訴你你想看到什麼,但也將引發對每個數據庫錯誤,而所謂的「顧客」表。你將需要制定一個邏輯來處理這個問題。

拉吉

+1

+1這是一個非常緊湊的解決方案,但我cho另一個是因爲你的解決方案包含許多結果表,而另一個不是 – LaBracca

+3

可能值得一提的是,sp_MSForEachDB沒有記錄,不受支持,並且有一些已知問題,如Aaron Bertrand在這裏http://sqlblog.com/blogs/aaron_bertrand /archive/2010/12/29/a-more-reliable-and-more-flexible-sp-msforeachdb.aspx。 –

5

怎麼是這樣的:

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 
+0

這是一個有用的通用代碼片段,我用'sys.tables'替換了'sys.databases',用於完全不同的目的,使用相同的樣板。 –

+2

你已經忘記在腳本中聲明[at] db_name,你需要添加一行:DECLARE @db_name NVARCHAR(150),否則非常有用的腳本:-) – inkubpl

+0

臨時表在哪裏被刪除? – Phil3992

相關問題