【问题标题】:Get all database names from multiple servers从多个服务器获取所有数据库名称
【发布时间】:2016-09-23 14:45:58
【问题描述】:

我们有多个 SQL Server,其中大部分是独立的。我需要创建一个存储过程/视图,它将所有数据库名称从所有服务器插入到一个表中。

有没有办法通过存储过程或视图来做到这一点?我没有任何 powershell 或 .Net 经验。

这是我目前所拥有的。我只是不知道如何从一个服务器“跳转”到另一个服务器并将我所有的结果添加到一个真实的表中。

CREATE TABLE ##temp 
(
DATABASE_NAME VARCHAR(100),
DATABASE_SIZE INT,
REMARKS VARCHAR(500)
)


INSERT into ##temp
EXEC [sp_databases] 

--doing this to also get ServerName along with the db name.  
--When I insert into a real table, I'll seperate it into two columns plus remove "@_!_@"
update ##temp
set DATABASE_NAME =   (select  @@SERVERNAME ) + '@_!_@ ' + DATABASE_NAME
where DATABASE_NAME not like '%@_!_@%' 

select DATABASE_NAME from ##temp

【问题讨论】:

  • 您可以通过Registered Servers窗口对多台服务器执行查询

标签: tsql sql-server-2008-r2 ssrs-2008-r2


【解决方案1】:

SQL Server Management Studio 允许您使用Registered Servers 功能执行query against multiple servers。这是在SQL Server 2008 as this tutorial shows 中添加的,因此您不必担心兼容性。

运行多服务器查询很容易:

  1. View 菜单中,选择“已注册的服务器”。这将打开一个类似于显示单个服务器对象的对象资源管理器的新窗口。
  2. Local Server Groups 文件夹中添加所有服务器连接详细信息的连接
  3. 右键单击本地服务器组文件夹并选择New Query。您在此处输入的查询将运行所有已注册的服务器。
  4. 要查找所有数据库运行select * from sys.databases 或只是sp_databases

SSMS 将从所有服务器收集结果并将它们显示在网格中。如果您希望结果转到单个服务器的表,则必须将目标服务器作为链接服务器添加到所有其他服务器,并使用四部分名称来定位目标表,例如 INSERT INTO myManagementServer.MyDb.dbo.ThatTable...

SQL Server 拥有更强大的功能来管理多台服务器。您可以通过Central Management Server 管理多台服务器,并通过策略将设置应用于多台服务器。该功能也是在 2008 年添加的。

在 SQL Server 2008 R2 中添加了SQL Server Utility,它更进一步,从多个服务器收集诊断、指标、性能数据并将其存储在管理仓库中以进行报告。想象一下,能够查看例如多台服务器的存储和查询性能,或过去 X 个月的可用空间趋势。

缺点是历史数据需要空间。收集它还需要向所有受监控的服务器添加一些存储过程,尽管这是自动完成的。

【讨论】:

    【解决方案2】:

    对于这种事情,最好至少有一台服务器与您需要信息的所有服务器建立链接连接。如果你这样做了,那么你可以使用我刚刚写的这个小脚本:

    -- (1) Create global temp table used to store results
    IF OBJECT_ID('tempdb..##databases') IS NOT NULL DROP TABLE ##databases;
    CREATE TABLE ##databases 
    (
      serverDBID   int identity,
      serverName   varchar(100),
      databaseName varchar(100),
      databaseSize decimal(20,6)
    );
    
    -- (2) Create and populate table variable used to collect server names
    DECLARE @servers TABLE(id int identity, serverName varchar(100));
    INSERT @servers(serverName)
    SELECT name FROM sys.servers;
    
    -- (3) loop through each DB and collect database names into ##databases
    DECLARE @i int = 1, @serverName varchar(100), @db varchar(100), @sql varchar(8000);
    WHILE @i <= (SELECT COUNT(*) FROM @servers)
    BEGIN
      SELECT @serverName = serverName FROM @servers WHERE id = @i;
    
      SET @sql = 'INSERT ##databases(serverName, databaseName) SELECT '''+@serverName+
                 ''', name FROM master.sys.databases';
      EXEC (@sql);
    
      SET @i += 1;
    END;
    
    -- (4) Collect database sizes
    SET @i = 1; -- reset/re-use @i;
    WHILE @i <= (SELECT COUNT(*) FROM ##databases)
    BEGIN
      SELECT @serverName = serverName, @db = databaseName
      FROM ##databases
      WHERE serverDBID = @i;
    
      SET @sql = 
      'UPDATE ##databases
       SET databaseSize = 
       (SELECT sum(size)/128. FROM ['+@serverName+'].['+@db+'].sys.database_files)
       WHERE serverDBID = '+CAST(@i AS varchar(4))+';'
    
      BEGIN TRY 
        EXEC (@sql);
      END TRY
      BEGIN CATCH
        PRINT 'There was an error getting dbsize info for '+@serverName+' > '+@db;
      END CATCH;
    
      SET @i += 1;
    END;
    
    -- Final Output
    SELECT * FROM ##databases;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      • 2021-05-27
      • 1970-01-01
      • 1970-01-01
      • 2018-01-15
      • 2014-03-21
      相关资源
      最近更新 更多