所有数据库查询结果的联合还包括数据库名称

use*_*149 5 sql-server

我希望有人可以提供帮助。我有许多服务器,每个服务器上都有多个数据库。所有的数据库都有一个表,我想用一个非常简单的“select count(*) from section”来查询。我想将结果加上数据库名称全部整理在一起(即不是作为单独的查询结果,我无法通过快速单击复制出来)。所以结果如下:

**DB Name** **Number of Sections**

Name1  10

Name2 20

Name3 11

Name4 9

Name5 20
Run Code Online (Sandbox Code Playgroud)

到目前为止,我有两个查询如下:

这个查询给了我一个结果列表作为一个查询,但是它没有给我结果相关的数据库名称,我无法确定如何添加它。

DECLARE @sql varchar(max);

SELECT @sql = Coalesce(@sql + ' UNION ALL ', '') + 'SELECT count(*) as ''Number of Sections'' FROM ' + QuoteName(name) + '.dbo.section'
FROM   sys.databases
where database_id > 4
;

EXEC (@sql);
Run Code Online (Sandbox Code Playgroud)

此查询为我提供了我想要的确切结果,但它们都是单独的查询,因此我必须手动遍历并复制每个查询以整理结果。

DECLARE @command varchar(1000) 

SELECT @command = 'IF ''?'' NOT IN(''master'', ''model'', ''msdb'', ''tempdb'') BEGIN USE ? SELECT ''?'', COUNT(*) FROM section END' 

EXEC sp_MSforeachdb @command 
Run Code Online (Sandbox Code Playgroud)

如果有人能给我一个关于如何获得我想要的输出的想法,我将不胜感激。

Ken*_*her 12

只需将 DBName 添加到您的第一个查询中:

DECLARE @sql varchar(max);

SELECT @sql = Coalesce(@sql + ' UNION ALL ', '') + 
        'SELECT '''+name+''' AS DBName, count(*) as ''Number of Sections'' FROM ' + QuoteName(name) + '.dbo.section' + CHAR(13)
FROM   sys.databases
where database_id > 4;

--PRINT @sql
EXEC (@sql);
Run Code Online (Sandbox Code Playgroud)

通常您希望避免 sp_msforeachdb。它有一些众所周知的错误。

编辑:如果你想在多台服务器上运行它,你可以编写一个快速的 SSIS 包,它循环遍历一个实例表并将数据收集到一个中心位置。我对以下 3 个帖子进行了演练:

将所有这些结合到这个答案中会有点长,但这里是基础知识:

  1. 在您的一个实例上创建一个实例表。
  2. 创建一个表来存储您要收集的数据(可能是同一个实例)。
  3. 在 SSIS 包中创建查询实例表并将结果存储在对象变量中的 SQL 任务。
  4. 为循环变量的每个循环创建一个。
  5. 在 for each 循环中,将对象变量中的变量更改为等于当前实例名称。
  6. 创建一个连接管理器,它使用表达式将server name属性更改为实例变量的内容。
  7. 在 for each 循环中创建一个数据流
    1. 数据流源使用带有表达式的连接管理器。
    2. 将收集数据的查询放在源中。
    3. 将目标设置为您在步骤 2 中创建的表。