Выбор данных с двух разных серверов в SQL Server

Как я могу выбрать данные в одном запросе из двух разных баз данных, которые находятся на двух разных серверах в SQL Server?


person Community    schedule 17.07.2009    source источник
comment
Ответы Эрика и Бешеного Быка очень кстати. Я смог использовать это для копирования больших объемов данных из DEV в PROD, сократив время с 5 часов до 18 часов до 17 секунд.   -  person Chris Aldrich    schedule 29.05.2015
comment
@Eric, спасибо за то, что отредактировал несколько двусмысленный вопрос и сделал его вопросом на 170 повторений :)   -  person Eric Wu    schedule 08.08.2016


Ответы (14)


То, что вы ищете, - это связанные серверы. Вы можете получить к ним доступ в SSMS из следующего места в дереве обозревателя объектов:

Server Objects-->Linked Servers

или вы можете использовать sp_addlinkedserver.

Вам нужно только настроить один. После этого вы можете вызвать таблицу на другом сервере следующим образом:

select
    *
from
    LocalTable,
    [OtherServerName].[OtherDB].[dbo].[OtherTable]

Обратите внимание, что владелец не всегда dbo, поэтому не забудьте заменить его любой схемой, которую вы используете.

person Eric    schedule 17.07.2009
comment
можем ли мы сделать это без связанных серверов? - person Steam; 15.01.2014
comment
@Eric, где объекты сервера в SSMS? - person Tsahi Asher; 15.09.2014
comment
@TsahiAsher - Когда вы подключаетесь к серверу, Server Objects - это папка в дереве Object Explorer. - person Eric; 25.09.2014
comment
Если не известно, вы также можете опустить схему, чтобы использовать значение по умолчанию. Например. [OtherServerName].[OtherDB]..[OtherTable] Однако лучше включить его, если он известен. - person Tom Bowers; 14.10.2015

Вы можете сделать это с помощью связанного сервера.

Обычно связанные серверы настроены так, чтобы компонент Database Engine мог выполнять инструкцию Transact-SQL, которая включает таблицы в другом экземпляре SQL Server или другом продукте базы данных, таком как Oracle. Многие типы источников данных OLE DB могут быть настроены как связанные серверы, включая Microsoft Access и Excel.

Связанные серверы предлагают следующие преимущества:

  • Возможность доступа к данным извне SQL Server.
  • Возможность отправлять распределенные запросы, обновления, команды и транзакции для разнородных источников данных на предприятии.
  • Возможность одинаково обращаться к разным источникам данных.

Узнайте больше о связанных серверах.

Выполните следующие действия, чтобы создать связанный сервер:

  1. Объекты сервера -> Связанные серверы -> Новый связанный сервер

  2. Укажите имя удаленного сервера.

  3. Выберите тип удаленного сервера (SQL Server или другой).

  4. Выберите Security -> Be made using this security context и укажите логин и пароль удаленного сервера.

  5. Нажмите ОК, и все готово!

Здесь представляет собой простое руководство по созданию связанного сервера.

ИЛИ

Вы можете добавить связанный сервер с помощью запроса.

Синтаксис:

sp_addlinkedserver [ @server= ] 'server' [ , [ @srvproduct= ] 'product_name' ] 
     [ , [ @provider= ] 'provider_name' ]
     [ , [ @datasrc= ] 'data_source' ] 
     [ , [ @location= ] 'location' ] 
     [ , [ @provstr= ] 'provider_string' ] 
     [ , [ @catalog= ] 'catalog' ] 

Подробнее о sp_addlinkedserver.

Вам необходимо создать связанный сервер только один раз. После создания связанного сервера мы можем запросить его следующим образом:

select * from LinkedServerName.DatabaseName.OwnerName.TableName
person Raging Bull    schedule 12.03.2014
comment
Примечание: см. здесь о том, как сделать имя сервера отличным от имени хоста / порта. - person Richard; 11.02.2015
comment
Небольшой совет, если у вас возникли проблемы с sp_addlinkedserver. Создайте сервер в диалоговом окне - убедитесь, что он работает - затем щелкните правой кнопкой мыши соединение и выберите скрипт, связанный сервер AS create - person Richard Housham; 19.08.2016

SELECT
        *
FROM
        [SERVER2NAME].[THEDB].[THEOWNER].[THETABLE]

Вы также можете посмотреть использование связанных серверов. Связанные серверы могут быть источниками данных других типов, например, платформами DB2. Это один из способов доступа к DB2 с помощью вызова SQL Server TSQL или Sproc ...

person RSolberg    schedule 17.07.2009
comment
будет ли этот метод работать постоянно? каковы сценарии, при которых он может выйти из строя? - person Steam; 15.01.2014
comment
Подтверждено, что это не удается в моем env, ошибка говорит, что мне нужно использовать addlinkedserver - person gorlaz; 14.03.2017
comment
Работает ли это для кого-нибудь без использования связанного сервера? - person Doug S; 13.02.2018
comment
протестировано и получена ошибка Could not find server '88.208.229.164' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers. - person WhatsThePoint; 11.04.2018

Запросы к 2 различным базам данных - это распределенный запрос. Вот список некоторых методов плюс плюсы и минусы:

  1. Связанные серверы. Предоставляют доступ к большему количеству источников данных, чем репликация SQL Server.
  2. Связанные серверы: подключайтесь к источникам данных, которые репликация не поддерживает или которым требуется специальный доступ.
  3. Связанные серверы: более эффективны, чем OPENDATASOURCE или OPENROWSET
  4. Функции OPENDATASOURCE и OPENROWSET: удобны для выборочного извлечения данных из источников данных. OPENROWSET также имеет возможности BULK, которые могут / не могут требовать файл формата, который может быть fiddley
  5. OPENQUERY: не поддерживает переменные.
  6. Все являются решениями T-SQL. Относительно легко реализовать и настроить
  7. Все зависят от соединения между источником и адресатом, что может повлиять на производительность и масштабируемость.
person super9    schedule 06.08.2009
comment
OPENQUERY по-прежнему требует связанный сервер, а OPENDATASOURCE не - person C J; 21.05.2020

Все это прекрасные ответы, но этого нет, и у него есть свои собственные мощные возможности. Возможно, это не соответствует тому, что хотел ОП, но вопрос был расплывчатым, и я чувствую, что другие могут найти здесь свой путь. В основном вы можете использовать одно окно для одновременного выполнения запроса к нескольким серверам, вот как:

В SSMS откройте зарегистрированные серверы и создайте новую группу серверов в разделе Группы локальных серверов.

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

Теперь вернитесь к группе, которую вы создали на первом шаге, щелкните правой кнопкой мыши и выберите New Query. Откроется новое окно запроса, и любой запрос, который вы запустите, будет выполняться на каждом сервере в группе. Результаты представлены в едином наборе данных с дополнительным именем столбца, указывающим, с какого сервера поступила запись. Если вы используете строку состояния, вы заметите, что имя сервера заменено на несколько.

person Paul    schedule 28.07.2016
comment
Похоже, предполагается, что запрос использует одни и те же таблицы во всех базах данных. (Что подходит для стандартных таблиц, таких как sys.tables, но маловероятно для пользовательских таблиц, таких как dbo.mycustomers) - person Dennis Jaheruddin; 29.11.2017
comment
Учитывая, что это один и тот же запрос из двух разных баз данных, весьма вероятно, что будут одни и те же таблицы. Но да, я обычно использую этот метод для производственной системы, размещенной на нескольких серверах, и для запросов к таблицам MSDB. - person Paul; 29.11.2017
comment
Действительно классная функция. Недостатком является то, что схема результирующего набора должна совпадать, поскольку он выполняет запрос дважды и объединяет их все одновременно. Было бы здорово, если бы вы могли ссылаться на серверы внутри самого SQL, как вы можете со связанными серверами, даже если вы не можете присоединиться к результирующему набору, и наборы должны были быть созданы для отдельной оценки. - person Kross; 24.05.2019
comment
@Kross, ты вроде бы мог. Создайте таблицу #output, выполните логику на основе @@ SERVERNAME и заполните данные в #output, а затем завершите ее выбором на этом. Я сделал то же самое для запроса информации журнала из смеси машин SQL2000 и SQL2008R2, которые имели разные уровни / столбцы информации, но вместо @@ SERVERNAME я использовал переменную версии сервера. - person Paul; 29.05.2019
comment
Это прекрасный ответ, и год спустя кто-то еще искал именно его. Спасибо - person user9930055; 09.07.2020

попробуй это:

SELECT * FROM OPENROWSET('SQLNCLI', 'Server=YOUR SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a
UNION
SELECT * FROM OPENROWSET('SQLNCLI', 'Server=ANOTHER SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a
person Anna Karthi    schedule 14.12.2013

У меня была такая же проблема с подключением SQL_server 2008 к SQL_server 2016, размещенному на удаленном сервере. Другие ответы не сработали для меня. Я пишу здесь свое измененное решение, так как думаю, что оно может быть полезно для кого-то еще.

Расширенный ответ для удаленных IP-подключений к базе данных:

Шаг 1. Свяжите серверы

EXEC sp_addlinkedserver @server='SRV_NAME',
   @srvproduct=N'',
   @provider=N'SQLNCLI',   
   @datasrc=N'aaa.bbb.ccc.ddd';

EXEC sp_addlinkedsrvlogin 'SRV_NAME', 'false', NULL, 'your_remote_db_login_user', 'your_remote_db_login_password'

... где SRV_NAME - вымышленное имя. Мы будем использовать его для ссылки на удаленный сервер из наших запросов. aaa.bbb.ccc.ddd - это IP-адрес удаленного сервера, на котором размещена ваша база данных SQLserver.

Шаг 2. Выполните запросы. Например:

SELECT * FROM [SRV_NAME].your_remote_db_name.dbo.your_table

...вот и все!

Сведения о синтаксисе: sp_addlinkedserver и sp_addlinkedsrvlogin

person MarcM    schedule 03.05.2018

Создал определение связанного сервера на одном сервере для другого (для этого вам потребуется SA), а затем просто укажите на них четырехчастное именование (см. BOL).

person RBarryYoung    schedule 17.07.2009

Сервер 2008:

Когда в SSMS подключены к server1.DB1 и попробуйте:

SELECT  * FROM
[server2].[DB2].[dbo].[table1]

как отмечали другие, если это не сработает, это потому, что сервер не связан.

Я получаю сообщение об ошибке:

Не удалось найти сервер DB2 в sys.servers. Убедитесь, что указано правильное имя сервера. При необходимости выполните хранимую процедуру sp_addlinkedserver, чтобы добавить сервер в sys.servers.

Чтобы добавить сервер:

ссылка: Чтобы добавить сервер с помощью sp_addlinkedserver Ссылка: [1]: Чтобы добавить сервер с помощью sp_addlinkedserver

Чтобы увидеть, что находится на ваших sys.servers, просто запросите его:

SELECT * FROM [sys].[servers]
person user3586922    schedule 20.08.2015

Упрощенное решение для добавления связанных серверов

Первый сервер

EXEC sp_addlinkedserver @server='ip,port\instancename'

Второй вход

EXEC sp_addlinkedsrvlogin 'ip,port\instancename', 'false', NULL, 'remote_db_loginname', 'remote_db_pass'

Выполнять запросы из связанной с локальной базой данных

INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
person irfandar    schedule 05.11.2018

Как @ Super9 рассказал об OPENDATASOURCE с использованием аутентификации SQL Server с поставщиком данных SQLOLEDB. Я просто публикую здесь фрагмент кода для одной таблицы, которая находится в базе данных текущего сервера, где выполняется код, а другая - на другом сервере '192.166.41.123'

SELECT top 2 * from dbo.tblHamdoonSoft  tbl1 inner JOIN  
OpenDataSource('SQLOLEDB','Data Source=192.166.41.123;User ID=sa;Password=hamdoonsoft')
.[TestDatabase].[dbo].[tblHamdoonSoft1] tbl2 on tbl1.id = tbl2.id
person Muhammad Ashikuzzaman    schedule 17.11.2018

Я знаю, что это старый вопрос, но я использую синонимы. Предположительно, запрос выполняется на сервере базы данных A и ищет таблицу на сервере базы данных B, которая не существует на сервере A. Добавьте синоним в базу данных A, которая вызывает вашу таблицу с сервера B. Включите любые схемы или разные имена базы данных, просто вызовите имя таблицы как обычно, и это будет работать.

Нет необходимости связывать серверы, так как синонимы сами по себе являются своего рода связью.

person Niklas Henricson    schedule 24.03.2017
comment
Итак, что является синонимом в этом контексте? - person Oskar Berggren; 07.05.2018
comment
Это объект базы данных, который ссылается на базовый объект в другой базе данных. Подробнее здесь: docs.microsoft.com/en-us/sql/relational-databases/synonyms/ - person Niklas Henricson; 08.05.2018
comment
Круто, я не знал об этой функции. Однако вы также заявляете, что они избегают необходимости в связанном сервере, но я не понимаю, как это сделать. Сами по себе синонимы являются просто синонимом, а не содержат каких-либо конкретных возможностей удаленного взаимодействия. В примере B на docs.microsoft.com/en-us/sql/t-sql/statements/, они создают связанный сервер, прежде чем ссылаться на него по синониму. - person Oskar Berggren; 09.05.2018
comment
Правда, я предположил, что базы данных находятся в одной серверной среде. Конечно, вам всегда придется связывать базы данных, если они удалены друг от друга. Нет другого способа доступа с отношениями база данных к базе данных. - person Niklas Henricson; 09.05.2018

sp_addlinkedserver('servername')

так должно получиться так -

select * from table1
unionall
select * from [server1].[database].[dbo].[table1]
person ugio    schedule 27.02.2010

Объекты сервера ---> связанный сервер ---> новый связанный сервер

На связанном сервере напишите имя сервера или IP-адрес для другого сервера и выберите SQL Server. В разделе «Безопасность» выберите (выполняется с использованием этого контекста безопасности) Запишите логин и пароль для другого сервера.

Теперь подключено, затем используйте

Select * from [server name or ip addresses ].databasename.dbo.tblname
person Sameh    schedule 26.08.2015