我能夠成功查詢相同的表在多個數據庫如下:聯盟設置
DECLARE @command varchar(1000)
SELECT @command = 'select * from table'
EXEC sp_MSforeachdb @command
然而,所有這些結果都如預期,在不同的結果窗口返回。執行所有這些結果的聯合的最簡單方法是什麼?
我能夠成功查詢相同的表在多個數據庫如下:聯盟設置
DECLARE @command varchar(1000)
SELECT @command = 'select * from table'
EXEC sp_MSforeachdb @command
然而,所有這些結果都如預期,在不同的結果窗口返回。執行所有這些結果的聯合的最簡單方法是什麼?
另一種方法對皮膚這隻貓就是使用動態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);
請停止使用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;
這並不驗證柱結構是兼容的,但你會發現,出來很快。
'SELECT list of,columns FROM database.schema.object UNION ALL SELECT列表,of,列FROM database2 ...' – gvee
數據庫名稱因我運行此服務器的服務器而異,因此使用sp_MSforeachdb。 – Dan
'SELECT name FROM sys.databases';) – gvee