Beispielabfrage für SQL Server Linked Server

92

In Management Studio versuche ich, eine Abfrage auszuführen / einen Join zwischen zwei Verbindungsservern durchzuführen. Ist dies eine korrekte Syntax bei Verwendung von verknüpften Datenbankservern:

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

Stellen Sie einfach den Namen des Datenbankservers der Datenbank db.table voran?

bmw0128
quelle

Antworten:

185

Das Format sollte wahrscheinlich sein:

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

Zum Beispiel: DatabaseServer1.db1.dbo.table1


Aktualisieren : Ich weiß, dass dies eine alte Frage ist und die Antwort, die ich habe, richtig ist. Ich denke jedoch, dass jeder andere, der darüber stolpert, ein paar Dinge wissen sollte.

Beim Abfragen eines Verbindungsservers in einer Verknüpfungssituation wird nämlich die GESAMTE Tabelle vom Verbindungsserver wahrscheinlich auf den Server heruntergeladen, von dem die Abfrage ausgeführt wird, um die Verbindungsoperation auszuführen. Im Fall des OP werden sowohl table1von DB1als auch table1von DB2vollständig an den Server übertragen, der die Abfrage ausführt, vermutlich benanntDB3 .

Wenn Sie große Tabellen haben, kann dies sein dies zu einem Vorgang führen, dessen Ausführung lange dauert. Immerhin wird es jetzt durch Netzwerkverkehrsgeschwindigkeiten eingeschränkt, die um Größenordnungen langsamer sind als Speicher- oder sogar Plattenübertragungsgeschwindigkeiten.

Führen Sie nach Möglichkeit eine einzelne Abfrage für den Remoteserver durch, ohne sich einer lokalen Tabelle anzuschließen, um die benötigten Daten in eine temporäre Tabelle zu ziehen. Dann fragen Sie ab.

Wenn dies nicht möglich ist, müssen Sie sich die verschiedenen Dinge ansehen, die dazu führen würden, dass SQL Server die gesamte Tabelle lokal laden muss. Zum Beispiel mit GETDATE()oder sogar bestimmten Joins. Andere Leistungskiller schließen ein, keine angemessenen Rechte zu gewähren.

Weitere Informationen finden Sie unter http://thomaslarock.com/2013/05/top-3-performance-killers-for-linked-server-queries/ .

Nicht ich
quelle
11
Wenn der Name des Datenbankservers einen Bindestrich hat, müssen Sie ihn mit eckigen Klammern umgeben
bmw0128
4
@ bmw0128: Besser noch, verwenden Sie doppelte Anführungszeichen: Es wird von fast jeder Plattform unterstützt, im Gegensatz zu den eckigen Klammern von Microsoft.
2
Sie müssen auch eckige Klammern oder doppelte Anführungszeichen verwenden, wenn der Name des Datenbankservers einen Punkt enthält.
David Brunow
4
Wenn Sie sich über eines der Qualifikationsmerkmale nicht sicher sind, führen Sie im SSMS-Objekt-Explorer einen Drilldown zu einer Tabelle auf einem Verbindungsserver durch, klicken Sie mit der rechten Maustaste und wählen Sie die Skripttabelle als, SELECT To und New Query Editor-Fenster. Die resultierende SELECT-Anweisung enthält den korrekten, vollständig qualifizierten Pfad zur Tabelle. Ich hatte ein Mystery-Datenbank-Qualifikationsmerkmal bei der Arbeit mit Sybase und dies gab mir den richtigen Namen.
John Mo
Ich denke, Sie sagen zu Unrecht, dass die gesamte Tabelle übertragen wird. Können Sie einen Hinweis darauf geben, woher Sie diese Informationen haben? Ich habe gerade versucht, mich mit einer Tabelle mit 204 Millionen Zeilen (16 GB Daten, 6,6 GB Index) auf einem Verbindungsserver zu verbinden, und es dauerte 47 ms, um eine Verbindung zu 5 der Zeilen herzustellen, 7 ms bei der zweiten Abfrage, da die Daten vermutlich zwischengespeichert wurden. Wenn Ihr Join einen Tabellenscan für die verknüpfte Tabelle erfordern würde, müsste er möglicherweise alles übertragen?
Jason Goemaat
31
SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME..TABLENAME')

Dies kann Ihnen helfen.

Akhilesh Kamate
quelle
Upvoted. Dies funktioniert, wenn Sie MySQL mit MS SQL verknüpfen.
Barry Guvenkaya
3
Mit anderen Worten, dies erstellt eine Pass-Through-Abfrage. Beachten Sie, dass die Abfrageanweisung in nativem SQL für den Server geschrieben werden muss. Syntax für Oracle unterscheidet sich von Teradata von SQL Server usw.
AxGryndr
10

Wenn Sie immer noch Probleme mit finden <server>.<database>.<schema>.<table>

Fügen Sie den Servernamen in ein []

Mian
quelle
Achtung: Ich habe eine Erstelltabelle aus select mit [] ausgeführt und anstatt auf dem Verbindungsserver erstellt zu werden, wurde die Tabelle lokal mit einem Namen wiedbo.databaseserver1.db1.dbo.table1
biscuit314
9

Wenn Sie Probleme mit diesen anderen Antworten haben , versuchen Sie esOPENQUERY

Beispiel:

 SELECT * FROM OPENQUERY([LinkedServer], 'select * from [DBName].[schema].[tablename]') 
Tom Stickel
quelle
Funktioniert für SQL Server
Tom Stickel
8

Sie müssen das Schema / den Eigentümer (standardmäßig dbo) als Teil der Referenz angeben. Außerdem ist es vorzuziehen, den neueren Join-Stil (ANSI-92) zu verwenden.

select foo.id 
    from databaseserver1.db1.dbo.table1 foo
        inner join databaseserver2.db1.dbo.table1 bar 
            on foo.name = bar.name
Joe Stefanelli
quelle
Die innere Join-Syntax ist den impliziten Joins vorzuziehen.
bmw0128
2
@ bmw0128: Ja, aus mehreren Gründen. IMHO ist das Wichtigste, dass es viel zu einfach ist, versehentlich einen produktübergreifenden Join zu schreiben, wenn Sie Ihre Tabellen und Joins an zwei verschiedenen Stellen haben.
Beachten Sie, dass die 4-Punkte-Teile für einige Nicht-SQL Server-Verbindungsserver NICHT funktionieren. Es kann einen Fehler wie ... auslösen. Für den Anbieter "MSDASQL" für den Verbindungsserver "MyLinkedServer" wurde ein ungültiges Schema oder ein ungültiger Katalog angegeben.
Brewmanz
6
select * from [Server].[database].[schema].[tablename] 

Dies ist der richtige Weg, um anzurufen. Stellen Sie sicher, dass die Server verbunden sind, bevor Sie die Abfrage ausführen!

So suchen Sie nach Verbindungsservern:

EXEC sys.sp_linkedservers 
Abhishek Jaiswal
quelle
Dies funktioniert bei einigen Nicht-SQL Server-Verbindungsservern NICHT. Es wird ein Fehler wie ... ausgelöst. Für den Anbieter "MSDASQL" für den Verbindungsserver "MyLinkedServer" wurde ein ungültiges Schema oder ein ungültiger Katalog angegeben.
Brewmanz
4
select name from drsql01.test.dbo.employee
  • drslq01 ist ein servernmae-verknüpfter Serer
  • Test ist der Datenbankname
  • dbo ist ein Schema - Standardschema
  • Mitarbeiter ist Tabellenname

Ich hoffe, es hilft zu verstehen, wie man eine Abfrage für einen Verbindungsserver ausführt

Jaspreet Singh
quelle
2

Normalerweise sollten direkte Abfragen bei Verbindungsservern nicht verwendet werden, da sie häufig die temporäre Datenbank von SQL Server verwenden. Im ersten Schritt werden Daten in die temporäre Datenbank abgerufen und anschließend gefiltert. Es gibt viele Themen dazu. Es ist besser, open OPENQUERY zu verwenden, da SQL an den Quell-Verbindungsserver übergeben wird und dann gefilterte Ergebnisse zurückgegeben werden, z

SELECT *
FROM OPENQUERY(Linked_Server_Name , 'select * from TableName where ID = 500')
Muhammad Yaseen
quelle
Diese Antwort enthält keinen Datenbanknamen
Chris Nevill
2
Ich habe beim Erstellen des Verbindungsservers Datenbankinformationen angegeben. Für Details können Sie unten MSDN Link sehen: msdn.microsoft.com/en-us/library/ff772782(v=sql.110).aspx
Muhammad Yaseen
Was kann ich tun, wenn mein Verbindungsserver eine Authentifizierung erfordert und ich nur versuche, mithilfe von PDO eine Abfrage von meiner PHP-Anwendung durchzuführen?
Nekiala
Wie würden Sie mit diesem Ansatz einen Join von Datenbank 1 zu Datenbank auf einem Verbindungsserver durchführen?
eaglei22
2

Für das, was es wert ist, fand ich die folgende Syntax, um am besten zu funktionieren:

SELECT * FROM [LINKED_SERVER] ... [TABLE]

Ich konnte die Empfehlungen anderer unter Verwendung des Datenbanknamens nicht zum Laufen bringen. Darüber hinaus hat diese Datenquelle kein Schema.

Sean Warren
quelle
2

Klicken Sie mit der rechten Maustaste auf eine Tabelle und klicken Sie als Auswahl auf Skripttabelle

Geben Sie hier die Bildbeschreibung ein

Shimon Doodkin
quelle
Das hat das OP nicht gefragt
Fandango68
2
Dies zeigt, wie Sie die richtige Syntax für die Auswahlabfrage für eine verknüpfte Tabelle erhalten. Das Ergebnis ist wie von Sean Antwort
Shimon Doodkin
1
@ ShimonDoodkin, ein hervorragendes Beispiel dafür, geben Sie mir keinen Fisch, aber bringen Sie mir bei, wie man fischt
Amro
0

Die folgende Abfrage funktioniert am besten.

Versuchen Sie diese Abfrage:

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

Es ist sehr hilfreich, MySQL mit MS SQL zu verknüpfen

Vijay S.
quelle
0

PostgreSQL :

  1. Sie müssen im Datenquellen- DSN einen Datenbanknamen angeben .
  2. Führen Sie Management Studio als Administrator aus
  3. Sie müssen den DBName in der Abfrage weglassen :

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

Shadi Namrouti
quelle