k1lex
@k1lex
Программист торг. сети. C# (WPF, WinForms), T-SQL

Как получить данные запросом SQL c нескольких слинкованных серверов?

В сети имеется порядка 40 SQL серверов, все они слинкованны на один сервер. Сервера отличаются только набором данных, структура баз одна, пароль для SA один для всех.

Со всех серверов необходимо собрать данные с помощью SQL скрипта. Пример скрипта ниже.
SELECT [Cashes].[CashName],
 CashDevices.[DeviceModel]
,[Cashes].Model 
,[Cashes].[RegistryNumber] 
,[Cashes].[DataChange] 
FROM [SES].[dbo].[CashDevices]
inner join  [SES].[dbo].[Cashes] Cashes ON [Cashes].ID=[CashDevices].[ID_Cash]
WHERE [DeviceType]='Фиск.память'


Проблема в том, что не знаю как организовать автоматическое задание на t-SQL что бы получать данные со всех серверов автоматически в одну необходимую мне таблицу.

Прошу хотя бы помочь советом в каком направлении искать решение.

Используется MS SQL 2008
  • Вопрос задан
  • 3004 просмотра
Решения вопроса 1
@polarnik
Тестировщик
INSERT INTO "MainTable"
("ServerName", "CashName", "DeviceModel", "Model", "RegistryNumber", "DataChange")
SELECT
    -- Имя сервера-источника, чтобы не путаться
    'LinkedServer1' as "ServerName" 
    ,[Cashes].[CashName]
    ,[CashDevices].[DeviceModel]
    ,[Cashes].Model 
    ,[Cashes].[RegistryNumber] 
    ,[Cashes].[DataChange] 
FROM
    -- Указание источника <server>.<database>.<schema>.<table>
    [LinkedServer1].[SES].[dbo].[CashDevices] 
    inner join
        [LinkedServer1].[SES].[dbo].[Cashes] Cashes ON [Cashes].ID=[CashDevices].[ID_Cash]
WHERE [DeviceType]='Фиск.память'

Как-то так можно. Чтобы сделать x40, написать процедуру, параметром которой будет имя LinkedServer.

Согласно описанию
technet.microsoft.com/ru-ru/library/ms175129%28v=s...
UNION не поддерживается.
Но если всё-же поддерживается, можно сделать на каждом сервере View, возвращающее результат запроса. А на главном сервере написать один большой запрос (если памяти хватит, запрос выполнится). Это плохой стиль:
INSERT INTO "MainTable"
("ServerName", "CashName", "DeviceModel", "Model", "RegistryNumber", "DataChange")
SELECT "CashView".* FROM [LinkedServer1].[SES].[dbo].[CashView] "CashView"
UNION
SELECT "CashView".* FROM [LinkedServer2].[SES].[dbo].[CashView] "CashView"
UNION
SELECT "CashView".* FROM [LinkedServer3].[SES].[dbo].[CashView] "CashView"
UNION
SELECT "CashView".* FROM [LinkedServer4].[SES].[dbo].[CashView] "CashView"
...
UNION
SELECT "CashView".* FROM [LinkedServer40].[SES].[dbo].[CashView] "CashView"


- Определение источника данных по имени связанного сервера
technet.microsoft.com/ru-ru/library/ms190406%28v=s...
- Вставка строк с использованием вложенных запросов INSERT и SELECT
technet.microsoft.com/ru-ru/library/ms189872%28v=s...
- Получение имён всех связанных серверов
support2.microsoft.com/kb/203638/en-us

Согласно принципу минимальных привилегий, sa использовать излишне. На связанных серверах создайте учётные записи, которые будут иметь доступ на выборку из таблиц [SES].[dbo].[CashDevices] и [SES].[dbo].[Cashes]. С помощью этих учётных записей подключите все 40 связанных серверов к основному серверу. Дальше - дело техники.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы