Пример запроса связанного сервера 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?

bmw0128
источник

Ответы:

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
9

Для тех, у кого есть проблемы с этими другими ответами , попробуйтеOPENQUERY

Пример:

 SELECT * FROM OPENQUERY([LinkedServer], 'select * from [DBName].[schema].[tablename]') 
Том Стикель
источник
Работает для SQL Server
Том Стикель 07
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''
')

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

Агунг Пандуан
источник