Dan*_*Dan 1 sql t-sql sql-server
我可以成功查询多个数据库中的同一表,如下所示:
DECLARE @command varchar(1000)
SELECT @command = 'select * from table'
EXEC sp_MSforeachdb @command
Run Code Online (Sandbox Code Playgroud)
但是,所有这些结果都按预期方式在不同的结果窗口中返回。对所有这些结果进行合并的最简单方法是什么?
请停止使用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;
Run Code Online (Sandbox Code Playgroud)
这将忽略系统数据库,并且不会尝试访问当前不存在的任何数据库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;
Run Code Online (Sandbox Code Playgroud)
这不能验证列结构是否兼容,但是您会很快发现这一点。
归档时间: |
|
查看次数: |
4151 次 |
最近记录: |