Przykładowe zapytanie SQL Server Linked Server


94

Będąc w Management Studio, próbuję uruchomić zapytanie / wykonać połączenie między dwoma połączonymi serwerami. Czy to jest poprawna składnia przy użyciu połączonych serwerów bazy danych:

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

Zasadniczo, czy po prostu poprzedzasz nazwę serwera db w tabeli db.table?

Odpowiedzi:


188

Prawdopodobnie powinien mieć format:

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

Na przykład: DatabaseServer1.db1.dbo.table1


Aktualizacja : wiem, że to stare pytanie, a odpowiedź, którą mam, jest poprawna; jednak myślę, że każdy, kto się na to natknie, powinien wiedzieć kilka rzeczy.

Mianowicie, podczas wysyłania zapytań do serwera połączonego w sytuacji łączenia, CAŁA tabela z serwera połączonego zostanie prawdopodobnie pobrana na serwer, z którego zapytanie jest wykonywane w celu wykonania operacji łączenia. W przypadku OP, zarówno table1z , jak DB1i table1z DB2zostaną przesłane w całości do serwera wykonującego zapytanie, przypuszczalnie nazwanego DB3.

Jeśli masz duże tabele, może to spowodować wykonanie operacji, której wykonanie zajmie dużo czasu. W końcu jest teraz ograniczony przez prędkości ruchu sieciowego, które są o rząd wielkości wolniejsze niż pamięć, a nawet prędkości transferu dysku.

Jeśli to możliwe, przeprowadź pojedyncze zapytanie względem serwera zdalnego, bez dołączania do tabeli lokalnej, aby pobrać potrzebne dane do tabeli tymczasowej. Następnie zapytaj o to.

Jeśli nie jest to możliwe, należy przyjrzeć się różnym rzeczom, które spowodowałyby, że serwer SQL musiałby lokalnie załadować całą tabelę. Na przykład użycie GETDATE()lub nawet niektórych złączeń. Inni zabójcy wydajności obejmują nieprzyznawanie odpowiednich praw.

Więcej informacji można znaleźć pod adresem http://thomaslarock.com/2013/05/top-3-performance-killers-for-linked-server-queries/ .


11
jeśli nazwa
serwera

4
@ bmw0128: Jeszcze lepiej, użyj podwójnych cudzysłowów: jest obsługiwany przez prawie każdą platformę, w przeciwieństwie do nawiasów kwadratowych Microsoftu.

2
Należy również użyć nawiasów kwadratowych lub cudzysłowów, jeśli nazwa serwera bazy danych zawiera kropkę.
David Brunow

4
Jeśli nie masz pewności co do któregokolwiek z kwalifikatorów, przejdź do tabeli na serwerze połączonym w Eksploratorze obiektów SSMS, kliknij prawym przyciskiem myszy i wybierz opcję Tabela skryptów jako, WYBIERZ do i okno nowego edytora zapytań. Wynikowa instrukcja SELECT będzie zawierać poprawną, w pełni kwalifikowaną ścieżkę do tabeli. Miałem kwalifikator tajemniczej bazy danych podczas pracy z Sybase i to dało mi poprawną nazwę.
John Mo

Myślę, że mylisz się mówiąc, że cały stół zostanie przeniesiony. Czy możesz wskazać, skąd masz te informacje? Właśnie próbowałem połączyć się z tabelą z 204 milionami wierszy (dane 16 GB, indeks 6,6 GB) na połączonym serwerze i połączenie z 5 wierszami zajęło 47 ms, a przy drugim zapytaniu 7 ms, ponieważ dane były prawdopodobnie buforowane. Może gdyby twoje dołączenie wymagało skanowania stołu na połączonym stole, musiałoby to wszystko przenieść?
Jason Goemaat

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

To może ci pomóc.


Głosowano za. Działa to, gdy łączysz MySQL z MS SQL.
Baz Guvenkaya,

3
Innymi słowy, jest to tworzenie kwerendy przekazującej. Należy pamiętać, że instrukcja zapytania musi być napisana w rodzimym języku SQL dla serwera. Składnia Oracle różni się od Teradata inna niż SQL Server itp.
AxGryndr

11

Jeśli nadal masz problem z <server>.<database>.<schema>.<table>

Umieść nazwę serwera w []


Ostrożnie: wykonałem tworzenie tabeli z select przy użyciu [] i zamiast zostać utworzona na serwerze połączonym, tabela została utworzona lokalnie z nazwą taką jakdbo.databaseserver1.db1.dbo.table1
biscuit314

9

Jeśli masz problem z innymi odpowiedziami , spróbujOPENQUERY

Przykład:

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

Działa dla SQL Server
Tom Stickel,

8

Musisz określić schemat / właściciela (domyślnie dbo) jako część odniesienia. Zalecane byłoby również użycie nowszego stylu łączenia (ANSI-92).

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

składnia łączenia wewnętrznego jest lepsza niż niejawne łączenia?
bmw0128

2
@ bmw0128: Tak, z kilku powodów. IMHO, najważniejsze jest to, że zbyt łatwo jest przypadkowo napisać łączenie krzyżowe, gdy masz tabele i łączysz się w dwóch różnych miejscach.

Należy zauważyć, że części z 4 kropkami NIE DZIAŁA w przypadku niektórych połączonych serwerów innych niż SQL Server. Może wywołać błąd, taki jak ... Określono nieprawidłowy schemat lub katalog dla dostawcy „MSDASQL” dla serwera połączonego „MyLinkedServer”.
brewmanz

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

To jest właściwy sposób dzwonienia. Przed wykonaniem zapytania sprawdź, czy serwery są połączone!

Aby sprawdzić połączone serwery, zadzwoń:

EXEC sys.sp_linkedservers 

To NIE DZIAŁA w przypadku niektórych połączonych serwerów innych niż SQL Server. Powoduje to błąd, np. ... Określono nieprawidłowy schemat lub katalog dla dostawcy „MSDASQL” dla serwera połączonego „MyLinkedServer”.
brewmanz

4
select name from drsql01.test.dbo.employee
  • drslq01 to servernmae --linked serer
  • test to nazwa bazy danych
  • dbo to schemat-domyślny schemat
  • pracownik to nazwa tabeli

Mam nadzieję, że pomoże to zrozumieć, jak wykonać zapytanie dla serwera połączonego


2

Zwykle zapytania bezpośrednie nie powinny być używane w przypadku serwera połączonego, ponieważ intensywnie korzysta on z tymczasowej bazy danych serwera SQL. W pierwszym kroku dane są pobierane do tymczasowej bazy danych, a następnie następuje filtrowanie. Wątków na ten temat jest wiele. Lepiej jest użyć otwartego OPENQUERY, ponieważ przekazuje on SQL do źródłowego serwera połączonego, a następnie zwraca przefiltrowane wyniki, np

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

Ta odpowiedź nie zawiera nazwy bazy danych
Chris Nevill

2
Podałem informacje o bazie danych podczas tworzenia połączonego serwera. Szczegółowe informacje można znaleźć pod linkiem MSDN: msdn.microsoft.com/en-us/library/ff772782(v=sql.110).aspx
Muhammad Yaseen

Co mogę zrobić, jeśli mój serwer połączony wymaga uwierzytelnienia i po prostu próbuję wysyłać zapytania z mojej aplikacji PHP przy użyciu PDO?
nekiala

Jak wykonałbyś łączenie z bazy danych 1 do bazy danych na serwerze połączonym, używając tego podejścia?
eaglei

2

Jeśli chodzi o to, co jest warte, stwierdziłem, że następująca składnia działa najlepiej:

WYBIERZ * FROM [LINKED_SERVER] ... [TABELA]

Nie mogłem uzyskać rekomendacji innych do pracy, używając nazwy bazy danych. Ponadto to źródło danych nie ma schematu.


2

kliknij prawym przyciskiem myszy tabelę i kliknij tabelę skryptów jako opcję wyboru

wprowadź opis obrazu tutaj


Nie o to pytał PO
Fandango68

2
Pokazuje to, jak uzyskać poprawną składnię dla zapytania wybierającego w tabeli połączonej. wynik jest jak odpowiedź
seansa

1
@ShimonDoodkin, doskonały przykład nie dawaj mi ryby, ale naucz mnie łowić
Amro

0

Podążanie za zapytaniem działa najlepiej.

Spróbuj tego zapytania:

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

Bardzo pomaga połączyć MySQL z MS SQL


0

PostgreSQL :

  1. Musisz podać nazwę bazy danych w źródle danych DSN .
  2. Uruchom Management Studio jako administrator
  3. Musisz pominąć DBName w zapytaniu :

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


0

Zrobiłem, aby znaleźć typ danych w tabeli na serwerze link_server za pomocą zapytania openquery i wyniki były pomyślne.

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

To dla mnie praca

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.