2016-09-23 1 views
0

У нас есть несколько SQL-серверов, и большинство из них являются автономными. Мне нужно создать хранимую процедуру/представление, которая введет все имена баз данных в таблицу со всех серверов.Получить все имена баз данных с нескольких серверов

Есть ли способ сделать это с помощью хранимой процедуры или представления? У меня нет опыта в 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 "@[email protected]" 
update ##temp 
set DATABASE_NAME = (select @@SERVERNAME) + '@[email protected] ' + DATABASE_NAME 
where DATABASE_NAME not like '%@[email protected]%' 

select DATABASE_NAME from ##temp 
+0

Вы можете выполнять запросы к нескольким серверам через окно «Зарегистрированные серверы» –

ответ

1

Для этого достаточно иметь хотя бы один сервер, который имеет связанное соединение со всеми серверами, для которых вам нужна информация. Если вы это сделаете, вы можете использовать этот маленький скрипт, который я только что написал:

-- (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 '''[email protected]+ 
      ''', 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 ['[email protected]+'].['[email protected]+'].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 '[email protected]+' > '[email protected]; 
    END CATCH; 

    SET @i += 1; 
END; 

-- Final Output 
SELECT * FROM ##databases; 
2

SQL Server Management Studio позволяет выполнять query against multiple servers с помощью функции Registered Servers. Это было добавлено в SQL Server 2008 as this tutorial shows, поэтому вам не стоит беспокоиться о совместимости.

Выполнение запросов с несколькими серверами легко:

  1. В меню View, выберите `Зарегистрированные серверы. Это откроет новое окно, аналогичное Обозревателю объектов, которое отображает объекты одного сервера.
  2. Добавить соединения для всех серверов деталей соединения в папке Local Server Groups
  3. правой кнопкой мыши на папке Local Server Groups и выберите New Query. Запрос, который вы вводите здесь, будет запускать все зарегистрированные серверы.
  4. Чтобы найти все базы данных запустить select * from sys.databases или просто sp_databases

SSMS будет собирать результаты всех серверов и отображать их в виде сетки. Если вы хотите, чтобы результаты переходили на таблицу одного сервера, вам нужно будет добавить целевой сервер в качестве связанного сервера ко всем остальным и использовать имя из четырех частей для таргетинга на целевую таблицу, например INSERT INTO myManagementServer.MyDb.dbo.ThatTable...

SQL Сервер имеет еще более мощные функции для управления несколькими серверами. Вы можете управлять несколькими серверами через Central Management Server и применять настройки к нескольким серверам с помощью политик. Эта особенность была также добавлена ​​в 2008 году.

В SQL Server 2008 R2 добавлен SQL Server Utility, который идет еще дальше и собирает диагностику, показатели, данные о производительности с нескольких серверов и хранит их на складе управления для отчетности. Представьте, что вы можете видеть, например, производительность хранилища и запросов для нескольких серверов или тенденции свободного пространства за последние X месяцев.

Недостатки в том, что для исторических данных требуется пространство. Для его сбора также необходимо добавить некоторые хранимые процедуры на все контролируемые серверы, хотя это делается автоматически.