2014-02-05 125 views
-1

我能夠成功查詢相同的表在多個數據庫如下:聯盟設置

DECLARE @command varchar(1000) 
SELECT @command = 'select * from table' 
EXEC sp_MSforeachdb @command 

然而,所有這些結果都如預期,在不同的結果窗口返回。執行所有這些結果的聯合的最簡單方法是什麼?

+0

'SELECT list of,columns FROM database.schema.object UNION ALL SELECT列表,of,列FROM database2 ...' – gvee

+0

數據庫名稱因我運行此服務器的服務器而異,因此使用sp_MSforeachdb。 – Dan

+0

'SELECT name FROM sys.databases';) – gvee

回答

2

另一種方法對皮膚這隻貓就是使用動態SQL:

DECLARE @sql varchar(max); 

SELECT @sql = Coalesce(@sql + ' UNION ALL ', '') + 'SELECT list, of, columns FROM ' + QuoteName(name) + '.schema.table' 
FROM sys.databases 
; 

PRINT @sql 
--EXEC (@sql); 
3

請停止使用sp_MSforeachdb。爲了任何東西。認真。它的無證,不支持的,而壯觀破:

如果你知道所有的數據庫具有相同的表(和他們都有相同的結構!),你可以這樣做:

DECLARE @sql NVARCHAR(MAX); 

SET @sql = N''; 

SELECT @sql = @sql + N'UNION ALL SELECT col1,col2 /*, etc. */ 
    FROM ' + QUOTENAME(name) + '.dbo.tablename' 
FROM sys.databases WHERE database_id > 4 AND state = 0; 

SET @sql = STUFF(@sql, 1, 10, ''); 

EXEC sp_executesql @sql; 

這會忽略系統數據庫,並且不會嘗試訪問當前不是ONLINE的任何數據庫。

現在,您可能需要進一步對其進行過濾,例如,不包括任何沒有名爲tablename的表的數據庫。你需要窩動態SQL在這種情況下,例如:

DECLARE @sql NVARCHAR(MAX); 

SET @sql = N'DECLARE @cmd NVARCHAR(MAX); 

SET @cmd = N'''';'; 

SELECT @sql = @sql + N' 

SELECT @cmd = @cmd + N''UNION ALL 
SELECT col1,col2 /*, etc. */ FROM ' 
    + QUOTENAME(name) + '.dbo.tablename '' 
WHERE EXISTS (SELECT 1 FROM ' + QUOTENAME(name) 
+ '.sys.tables AS t 
INNER JOIN ' + QUOTENAME(name) + '.sys.schemas AS s 
ON t.[schema_id] = s.[schema_id] 
WHERE t.name = N''tablename'' 
AND s.name = N''dbo'');' 
FROM sys.databases WHERE database_id > 4 AND state = 0; 

SET @sql = @sql + N'; 

SET @cmd = STUFF(@cmd, 1, 10, ''''); 

PRINT @cmd; 
--EXEC sp_executesql @cmd;'; 

PRINT @sql; 
EXEC sp_executesql @sql; 

這並不驗證柱結構是兼容的,但你會發現,出來很快。