2015-10-02 3 views
1

Я пытаюсь настроить запрос, который захватит версию Windows каждого SQL Server, который у меня есть, и выбросить в таблицу. У меня есть запрос, который захватывает версию, но я думаю, что есть лучший способ получить необходимую информацию, чем подключение к каждому отдельному серверу один за другим для запуска запроса. Я не против использования XP_cmdshell. Мне просто интересно, есть ли способ запустить один запрос, который захватит версию каждой ОС Windows, которую я имею на серверах sql. Также у меня есть список серверов для использования.Запросить несколько SQL-серверов в одном запросе

EDIT: Я знаю, что мне придется каким-то образом коснуться каждого сервера. Я просто хотел бы, чтобы обойти RDP для каждого сервера и открыть SQL-сервер и запросить его или подключиться к каждому серверу на сервере sql и запускать запрос один за другим.

Все, что у меня есть сейчас, код мудрый - это просто ЗАЯВЛЕНИЕ ВСТАВКИ, которое я получаю здесь, и я рисую пробел о том, куда идти дальше, даже мотыгой, чтобы решить проблему. В приведенной ниже таблице есть два столбца ServerName и Win_Ver ServerName уже заполнены всеми серверами, которые у меня есть.

INSERT INTO mtTable 
(Win_Ver) 

SELECT @@Version 
+1

можете ли вы опубликовать код, который у вас есть в настоящее время? также, является ли ваш вопрос об улучшении эффективности вашего запроса другими способами, кроме подключения к каждому серверу? потому что другого пути не будет - вам нужно будет запросить каждый сервер в той или иной форме, чтобы получить информацию. –

+0

Умм, это НЕ версия окон каждого сервера, это информация о версии сервера sql. Вам нужно будет выполнить этот запрос на каждом экземпляре сервера sql. На самом деле это не так. –

+1

Ознакомьтесь с LINKED SERVERS и удаленными вызовами процедур. Связанный сервер позволит вам запрашивать разные серверы Sql, но я думаю, что версия @@ остается локальной, если вы не используете Remote Procedure Call (в основном, выполните ваш запрос на удаленном сервере). Возможно, я ошибаюсь, поэтому дважды проверяю. –

ответ

0

В SQL Server вы можете создать Linked Server, который вы можете запросить с другого сервера.

На сервере вы хотите написать запрос в:

Откройте Обозреватель объектов
Перейти к Серверу объектов
Щелкните правой кнопкой мыши Связанные серверы и добавьте новый связанный сервер

добавить имя ваш сетевой сервер, выберите SQL-сервер и обязательно определите роли безопасности.

+0

Спасибо, я прошу об этом, но я должен был добавить, что моя группа хмурится в использовании связанных серверов, потому что они могут легко сломаться. –

+0

Я считаю, что лучший способ добавить связанный сервер - добавить серверный сервер на сервер, на который вы ссылаетесь, и в разделе безопасности ссылки вы добавляете этот логин. Я использую логины, которые специально предназначены для связи между серверами. –

+0

Я ценю помощь, но я не могу добавить связанные серверы и добавить понравившийся сервер с каким-то случайно созданным пользователем SQL, это еще худший способ исправить проблемы, которые они могут вызвать. –

1

Учитывая, что:

  • «Есть около 112 серверов»
  • серверы являются «смесью между 2008 - 2012»
  • «Существует таблица мы держим со всеми нашими БД сервера Статистика."
  • и «Мы периодически спрашивают, чтобы произвести эту статистику»

один вариант заключается в цикле через эту таблицу серверов с помощью курсора, и для каждого из них, выполнить xp_cmdshell для вызова SQLCMD для выполнения запроса. Вы должны использовать переменную таблицы для захвата набора результатов из SQLCMD, возвращаемого xp_cmdshell. Что-то вроде:

DECLARE @ServerName sysname, 
     @Command NVARCHAR(4000), 
     @CommandTemplate NVARCHAR(4000); 

DECLARE @Results TABLE ([ResultID] INT IDENTITY(1, 1) NOT NULL, [Result] NVARCHAR(4000)); 

SET @CommandTemplate = N'SQLCMD -S {{SERVER_NAME}} -E -h-1 -Q "PRINT @@VERSION;"'; 

DECLARE srvrs CURSOR LOCAL READ_ONLY FAST_FORWARD 
FOR SELECT [ServerName] 
     FROM ServerStats; 

OPEN srvrs; 

FETCH NEXT 
FROM srvrs 
INTO @ServerName; 

WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    SET @Command = REPLACE(@CommandTemplate, N'{{SERVER_NAME}}', @ServerName); 

    INSERT INTO @Results ([Result]) 
    EXEC xp_cmdshell @Command; 

    -- Get results via SELECT [Result] FROM @Results ORDER BY [ResultID]; 
    -- Do something with the data in @Results 

    DELETE FROM @Results; 

    FETCH NEXT 
    FROM srvrs 
    INTO @ServerName; 
END; 

CLOSE srvrs; 
DEALLOCATE srvrs; 

И это не мешало бы бросить в TRY/CATCH там :-).

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

+0

Если вы хотите выполнить 'EXEC xp_cmdshell @Command;', то '@ Command' должен быть' sysname' datatype, а не 'NVARCHAR (MAX)'. Есть более эффективные способы петли, чем использование курсора. Чтобы немного очистить выход, попробуйте установить переменную на @@, а затем ПЕЧАТЬ, а не просто выбрать ее. –

+0

@BrianStork Спасибо за отзыв. ** 1) ** [xp_cmdshell] (https://msdn.microsoft.com/en-us/library/ms175046.aspx), принимает либо 'NVARCHAR (4000)', либо 'VARCHAR (8000)'. Я не мог вспомнить, было ли «NVARCHAR» 4000 или MAX, и надеялся, что «MAX» будет работать, так как команды DOS могут быть> 4000 символов. Ну что ж. Но 'sysname' является псевдонимом для' NVARCHAR (128) 'и используется для имен объектов и т. Д. ** 2) **« лучшие способы петли, чем использование курсора »- это миф, который был опроверг несколько times и ** 3) ** 'PRINT' и' SELECT' дают одинаковый вывод, но 'PRINT не нуждается в' SET NOCOUNT', поэтому я исправлю это. –

+0

Спасибо за код, но я получаю ошибки: Msg 155, Level 15, State 2, Line 9 «READONLY» не является признанным вариантом CURSOR. Msg 137, уровень 15, состояние 1, строка 22 Должен объявить скалярную переменную «@Commmand». Я использую SQL Server 2008 R2 для выполнения запроса, и я не знаю, являются ли команды конкретными для более поздней версии или если я что-то упускаю. –

Смежные вопросы