Пример запроса связанного сервера SQL Server


94

Находясь в Management Studio, я пытаюсь выполнить запрос / выполнить соединение между двумя связанными серверами. Это правильный синтаксис с использованием связанных серверов БД:

select foo.id 
from databaseserver1.db1.table1 foo, 
     databaseserver2.db1.table1 bar 
where foo.name=bar.name

В принципе, вы просто указываете имя сервера db перед таблицей db.table?

Ответы:


188

Формат, вероятно, должен быть:

<server>.<database>.<schema>.<table>

Например: DatabaseServer1.db1.dbo.table1


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

А именно, при запросе к связанному серверу в ситуации соединения ВСЯ таблица со связанного сервера, вероятно, будет загружена на сервер, с которого выполняется запрос, для выполнения операции соединения. В случае OP и table1from, DB1и table1from DB2будут полностью переданы на сервер, выполняющий запрос, предположительно названный DB3.

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

Если возможно, выполните один запрос к удаленному серверу без присоединения к локальной таблице, чтобы вытащить нужные данные во временную таблицу. Затем спросите об этом.

Если это невозможно, вам нужно посмотреть на различные вещи, из-за которых SQL-сервер должен загружать всю таблицу локально. Например, использование GETDATE()или даже определенные объединения. Другие убийцы производительности включают отсутствие соответствующих прав.

См. Http://thomaslarock.com/2013/05/top-3-performance-killers-for-linked-server-queries/ для получения дополнительной информации.


11
если в имени
сервера

4
@ bmw0128: А еще лучше использовать двойные кавычки: это поддерживается почти всеми платформами, в отличие от квадратных скобок Microsoft.

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

4
Если вы не уверены в каком-либо из квалификаторов, перейдите к таблице на связанном сервере в обозревателе объектов SSMS, щелкните правой кнопкой мыши и выберите «Таблица сценариев как», «ВЫБРАТЬ К» и «Новое окно редактора запросов». Результирующий оператор SELECT будет содержать правильный полный путь к таблице. При работе с Sybase у меня был квалификатор mystery database, и это дало мне правильное имя.
Джон Мо

Думаю, вы ошибаетесь, говоря, что вся таблица будет перенесена. Не могли бы вы указать, откуда вы взяли эту информацию? Я просто попытался присоединиться к таблице с 204 миллионами строк (данные 16 ГБ, индекс 6,6 ГБ) на связанном сервере, и потребовалось 47 мс для связи с 5 строками, 7 мс по второму запросу, поскольку данные предположительно были кэшированы. Может быть, если для вашего соединения потребуется сканирование таблицы связанной таблицы, ему придется все это передать?
Джейсон Гоэмаат, 03

32
SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME..TABLENAME')

Это может вам помочь.


Проголосовали. Это работает, когда вы связываете MySQL с MS SQL.
База Гувенькая 07

3
Другими словами, это создает сквозной запрос. Имейте в виду, что оператор запроса должен быть написан на собственном SQL для сервера. Синтаксис Oracle, отличного от Teradata, от SQL Server и т. Д.
AxGryndr

11

Если вы все еще сталкиваетесь с проблемой <server>.<database>.<schema>.<table>

Вложите имя сервера в []


Осторожно: я выполнил создание таблицы из select с помощью [], и вместо того, чтобы быть созданной на связанном сервере, таблица была создана локально с таким именем, какdbo.databaseserver1.db1.dbo.table1
biscuit314


8

Вам необходимо указать схему / владельца (по умолчанию dbo) как часть ссылки. Также было бы предпочтительнее использовать новый стиль соединения (ANSI-92).

select foo.id 
    from databaseserver1.db1.dbo.table1 foo
        inner join databaseserver2.db1.dbo.table1 bar 
            on foo.name = bar.name

синтаксис внутреннего соединения предпочтительнее неявного соединения?
bmw0128 03

2
@ bmw0128: Да, по нескольким причинам. ИМХО, наиболее важно то, что слишком легко случайно написать соединение кросс-продукта, когда у вас есть таблицы и соединения в двух разных местах.

Обратите внимание, что части, разделенные точками, НЕ РАБОТАЮТ для некоторых серверов, связанных не с SQL-Server. Это может вызвать ошибку, например ... Недопустимая схема или каталог были указаны для поставщика "MSDASQL" для связанного сервера "MyLinkedServer".
brewmanz

6
select * from [Server].[database].[schema].[tablename] 

Это правильный способ звонка. Перед выполнением запроса убедитесь, что серверы связаны!

Чтобы проверить наличие связанных серверов, позвоните:

EXEC sys.sp_linkedservers 

Это НЕ РАБОТАЕТ для некоторых серверов, связанных не с SQL-Server. Это вызывает ошибку, например ... Недопустимая схема или каталог были указаны для поставщика "MSDASQL" для связанного сервера "MyLinkedServer".
brewmanz

4
select name from drsql01.test.dbo.employee
  • drslq01 - это servernmae - связанный serer
  • test - это имя базы данных
  • dbo - это схема-схема по умолчанию
  • сотрудник - имя таблицы

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


2

Обычно прямые запросы не следует использовать в случае связанного сервера, потому что он сильно использует временную базу данных SQL-сервера. На первом этапе данные извлекаются во временную БД, после чего происходит фильтрация. Об этом много тредов. Лучше использовать открытый OPENQUERY, потому что он передает SQL на исходный связанный сервер, а затем возвращает отфильтрованные результаты, например

SELECT *
FROM OPENQUERY(Linked_Server_Name , 'select * from TableName where ID = 500')

Этот ответ не включает имя базы данных
Крис Невилл,

2
Я предоставил информацию о базе данных при создании связанного сервера. Подробности вы можете увидеть ниже по ссылке MSDN: msdn.microsoft.com/en-us/library/ff772782(v=sql.110).aspx
Мухаммад Ясин

Что я могу сделать, если мой связанный сервер требует аутентификации, а я просто пытаюсь запросить из своего PHP-приложения с помощью PDO?
nekiala

Как с помощью этого подхода выполнить соединение базы данных 1 с базой данных на связанном сервере?
eaglei22

2

Как бы то ни было, я обнаружил, что следующий синтаксис работает лучше всего:

ВЫБРАТЬ * С [LINKED_SERVER] ... [ТАБЛИЦА]

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


2

щелкните правой кнопкой мыши таблицу и щелкните таблицу сценариев как выберите

введите описание изображения здесь


OP спросил не об этом
Fandango68

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

1
@ShimonDoodkin, отличный пример: «Не давайте мне рыбу, но научите меня ловить рыбу»
Амро

0

Лучше всего подходит следующий запрос.

Попробуйте этот запрос:

SELECT * FROM OPENQUERY([LINKED_SERVER_NAME], 'SELECT * FROM [DATABASE_NAME].[SCHEMA].[TABLE_NAME]')

Очень помогает связать MySQL с MS SQL


0

PostgreSQL :

  1. Вы должны указать имя базы данных в DSN источника данных. .
  2. Запустите Management Studio от имени администратора
  3. Вы должны опустить DBName в запросе :

    SELECT * FROM OPENQUERY([LinkedServer], 'select * from schema."tablename"')


0

Я сделал, чтобы узнать тип данных в таблице на link_server, используя openquery, и результаты были успешными.

SELECT * FROM OPENQUERY (LINKSERVERNAME, '
SELECT DATA_TYPE, COLUMN_NAME
FROM [DATABASENAME].INFORMATION_SCHEMA.COLUMNS
WHERE 
     TABLE_NAME  =''TABLENAME''
')

Это работа для меня

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.