Auswählen von Daten von zwei verschiedenen Servern in SQL Server


363

Wie kann ich Daten in derselben Abfrage aus zwei verschiedenen Datenbanken auswählen, die sich auf zwei verschiedenen Servern in SQL Server befinden?


6
Die Antworten von Eric und Raging Bull sind sehr praktisch. Ich konnte dies verwenden, um Massen von Datenmengen von DEV nach PROD zu kopieren und die Zeiten von 5 Stunden bis 18 Stunden bis zu 17 Sekunden zu verkürzen.
Chris Aldrich

@ Eric, ein großes Lob für die Bearbeitung einer geringfügig mehrdeutigen Frage und die Erstellung einer Frage mit 170 Wiederholungen :)
Eric Wu

Antworten:


345

Was Sie suchen, sind Verbindungsserver. Sie können sie in SSMS von der folgenden Stelle in der Baumstruktur des Objekt-Explorers aus erreichen:

Server Objects-->Linked Servers

oder Sie können sp_addlinkedserver verwenden .

Sie müssen nur eine einrichten. Sobald Sie das haben, können Sie eine Tabelle auf dem anderen Server wie folgt aufrufen:

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

Beachten Sie, dass der Eigentümer nicht immer dboist. Ersetzen Sie ihn daher durch das von Ihnen verwendete Schema.


13
können wir es ohne Verbindungsserver tun?
Steam

5
@ Eric, wo sind Serverobjekte in SSMS?
Tsahi Asher

9
@TsahiAsher - Wenn Sie eine Verbindung zu einem Server herstellen, ist Server Objects ein Ordner in der Baumstruktur des Objekt-Explorers.
Eric

2
Wenn nicht bekannt, können Sie das Schema auch weglassen, um die Standardeinstellung zu verwenden. ZB Es ist [OtherServerName].[OtherDB]..[OtherTable]jedoch am besten, es einzuschließen, wenn es bekannt ist.
Tom Bowers

92

Sie können dies mit Linked Server tun.

In der Regel sind Verbindungsserver so konfiguriert, dass das Datenbankmodul eine Transact-SQL-Anweisung ausführen kann, die Tabellen in einer anderen Instanz von SQL Server oder einem anderen Datenbankprodukt wie Oracle enthält. Viele Arten von OLE DB-Datenquellen können als Verbindungsserver konfiguriert werden, einschließlich Microsoft Access und Excel.

Verbindungsserver bieten folgende Vorteile:

  • Die Möglichkeit, von außerhalb von SQL Server auf Daten zuzugreifen.
  • Die Möglichkeit, verteilte Abfragen, Aktualisierungen, Befehle und Transaktionen für heterogene Datenquellen im gesamten Unternehmen auszugeben.
  • Die Fähigkeit, verschiedene Datenquellen auf ähnliche Weise anzusprechen.

Lesen Sie mehr über Verbindungsserver .

Führen Sie die folgenden Schritte aus, um einen Verbindungsserver zu erstellen:

  1. Serverobjekte -> Verbindungsserver -> Neuer Verbindungsserver

  2. Geben Sie den Namen des Remote-Servers an.

  3. Wählen Sie Remote Server Type (SQL Server oder Andere).

  4. Wählen Sie Sicherheit -> In diesem Sicherheitskontext erstellen und geben Sie die Anmeldung und das Kennwort des Remote-Servers an.

  5. Klicken Sie auf OK und Sie sind fertig !!

Hier ist ein einfaches Tutorial zum Erstellen eines Verbindungsservers.

ODER

Sie können einen Verbindungsserver mithilfe einer Abfrage hinzufügen.

Syntax:

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

Lesen Sie mehr über sp_addlinkedserver .

Sie müssen den Verbindungsserver nur einmal erstellen . Nach dem Erstellen des Verbindungsservers können wir ihn wie folgt abfragen:

select * from LinkedServerName.DatabaseName.OwnerName.TableName

Hinweis: Hier erfahren Sie, wie der Servername nicht der Hostname / Port ist.
Richard

1
Ein kleiner Tipp, wenn Sie Probleme mit dem sp_addlinkedserver haben. Erstellen Sie den Server im Dialog - stellen Sie sicher , es funktioniert - dann rechts klicken Sie auf die Verbindung und wählen Sie das Scrip [t Verbindungsserver AS erstellen
Richard Housham

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

Sie können sich auch die Verwendung von Verbindungsservern ansehen. Verbindungsserver können auch andere Arten von Datenquellen sein, z. B. DB2-Plattformen. Dies ist eine Methode für den Versuch, über einen SQL Server-TSQL- oder Sproc-Aufruf auf DB2 zuzugreifen ...


2
Wird diese Methode die ganze Zeit funktionieren? In welchen Szenarien könnte dies fehlschlagen?
Steam

3
Bestätigt, dass dies in meiner Umgebung fehlschlägt, Fehler sagt, dass ich addlinkedserver
gorlaz

1
Funktioniert dies für jeden, ohne einen Verbindungsserver zu verwenden?
Doug S

getestet und Fehler erhalten istCould 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.
WhatsThePoint

22

Das Abfragen über 2 verschiedene Datenbanken ist eine verteilte Abfrage. Hier ist eine Liste einiger Techniken sowie der Vor- und Nachteile:

  1. Verbindungsserver: Bieten Sie Zugriff auf eine größere Anzahl von Datenquellen als die SQL Server-Replikation bietet
  2. Verbindungsserver: Stellen Sie eine Verbindung zu Datenquellen her, die von der Replikation nicht unterstützt werden oder für die ein Ad-hoc-Zugriff erforderlich ist
  3. Verbindungsserver: Bessere Leistung als OPENDATASOURCE oder OPENROWSET
  4. OPENDATASOURCE- und OPENROWSET- Funktionen: Praktisch zum Abrufen von Daten aus Datenquellen auf Ad-hoc-Basis. OPENROWSET verfügt auch über BULK-Funktionen, für die möglicherweise eine Formatdatei erforderlich ist oder nicht
  5. OPENQUERY : Unterstützt keine Variablen
  6. Alle sind T-SQL-Lösungen. Relativ einfach zu implementieren und einzurichten
  7. Alle hängen von der Verbindung zwischen Quelle und Ziel ab, die die Leistung und Skalierbarkeit beeinträchtigen kann

OPENQUERY erfordert weiterhin einen Verbindungsserver, wie dies bei OPENDATASOURCE nicht der Fall ist
CJ

16

Versuche dies:

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

16

Dies sind alles gute Antworten, aber diese fehlt und hat ihre eigenen mächtigen Verwendungszwecke. Möglicherweise passt es nicht zu dem, was das OP wollte, aber die Frage war vage und ich glaube, andere finden hier ihren Weg. Grundsätzlich können Sie 1 Fenster verwenden, um gleichzeitig eine Abfrage für mehrere Server auszuführen. So geht's:

Öffnen Sie in SSMS Registrierte Server und erstellen Sie eine neue Servergruppe unter Lokale Servergruppen .

Erstellen Sie unter dieser Gruppe eine neue Serverregistrierung für jeden Server, den Sie abfragen möchten. Wenn die DB-Namen unterschiedlich sind, stellen Sie sicher, dass für jeden in den Eigenschaften ein Standard festgelegt wird.

Kehren Sie nun zu der Gruppe zurück, die Sie im ersten Schritt erstellt haben, klicken Sie mit der rechten Maustaste und wählen Sie Neue Abfrage. Ein neues Abfragefenster wird geöffnet und jede von Ihnen ausgeführte Abfrage wird auf jedem Server in der Gruppe ausgeführt. Die Ergebnisse werden in einem einzelnen Datensatz mit einem zusätzlichen Spaltennamen dargestellt, der angibt, von welchem ​​Server der Datensatz stammt. Wenn Sie die Statusleiste verwenden, werden Sie feststellen, dass der Servername durch mehrere ersetzt wird .


2
Dies scheint davon auszugehen, dass die Abfrage in allen Datenbanken dieselben Tabellen verwendet. (Was für Standardtabellen wie sys.tables in Ordnung ist, aber wahrscheinlich nicht für maßgeschneiderte Tabellen wie dbo.mycustomers)
Dennis Jaheruddin

Da es sich um "dieselbe Abfrage aus zwei verschiedenen Datenbanken" handelt, ist es sehr wahrscheinlich, dass dieselben Tabellen vorhanden sind. Aber ja, ich verwende diese Methode routinemäßig für ein Produktionssystem, das sich auf mehreren Servern befindet, und zum Abfragen von MSDB-Tabellen.
Paul

Wirklich cooles Feature. Der Nachteil ist, dass das Schema der Ergebnismenge übereinstimmen muss, da die Abfrage zweimal ausgeführt und alle gleichzeitig zusammengeführt werden. Es wäre großartig, wenn Sie auf die Server in SQL selbst verweisen könnten, wie Sie es mit verknüpften Servern tun können, selbst wenn Sie der Ergebnismenge nicht beitreten könnten und die Mengen so erstellt werden müssten, dass sie separat ausgewertet werden.
Kross

1
@Kross du könntest irgendwie. Erstellen Sie eine # output-Tabelle, führen Sie eine Logik basierend auf @@ SERVERNAME aus, füllen Sie die Daten in # output und beenden Sie sie mit einer Auswahl. Ich habe eine ähnliche Aktion zum Abfragen von Protokollinformationen von einer Mischung aus SQL2000- und SQL2008R2-Computern durchgeführt, die unterschiedliche Informationsebenen / -spalten hatten, aber anstelle von @@ SERVERNAME habe ich eine Serverversionsvariable verwendet.
Paul

9

Ich hatte das gleiche Problem beim Verbinden eines SQL_Servers 2008 mit einem SQL_Server 2016, der auf einem Remote-Server gehostet wird. Andere Antworten haben bei mir nicht einfach funktioniert. Ich schreibe hier meine optimierte Lösung, da ich denke, dass sie für jemand anderen nützlich sein kann.

Eine erweiterte Antwort für Remote-IP-Datenbankverbindungen:

Schritt 1: Server verbinden

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'

... wo SRV_NAMEist ein erfundener Name. Wir werden es verwenden, um aus unseren Abfragen auf den Remote-Server zu verweisen. aaa.bbb.ccc.dddist die IP-Adresse des Remote-Servers, auf dem sich Ihre SQL Server-Datenbank befindet.

Schritt 2: Führen Sie Ihre Abfragen aus. Zum Beispiel:

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

...und das ist es!

Syntaxdetails : sp_addlinkedserver und sp_addlinkedsrvlogin


4

Erstellt eine Verknüpfungsserverdefinition auf einem Server zum anderen (Sie benötigen dazu SA) und verweisen sie dann einfach mit einer 4-teiligen Benennung (siehe BOL).


4

Server 2008:

Wenn Sie in SSMS mit server1.DB1 verbunden sind, versuchen Sie Folgendes:

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

Wie andere angemerkt haben, liegt es daran, dass der Server nicht verbunden ist, wenn es nicht funktioniert.

Ich bekomme den Fehler:

Server DB2 konnte in sys.servers nicht gefunden werden. Stellen Sie sicher, dass der richtige Servername angegeben wurde. Führen Sie bei Bedarf die gespeicherte Prozedur sp_addlinkedserver aus, um den Server zu sys.servers hinzuzufügen.

So fügen Sie den Server hinzu:

Referenz: So fügen Sie einen Server mit sp_addlinkedserver hinzu Link: [1]: So fügen Sie einen Server mit sp_addlinkedserver hinzu

Um zu sehen, was sich in Ihren sys.servern befindet, fragen Sie es einfach ab:

SELECT * FROM [sys].[servers]

3
 select * 
 from [ServerName(IP)].[DatabaseName].[dbo].[TableName]

2

Wie @ Super9 über OPENDATASOURCE mit SQL Server-Authentifizierung mit dem Datenprovider SQLOLEDB berichtete . Ich poste hier nur ein Code-Snippet für eine Tabelle in der aktuellen Server - Datenbank, in der der Code ausgeführt wird, und eine andere in einem anderen Server '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

0
sp_addlinkedserver('servername')

also sollte es so gehen -

select * from table1
unionall
select * from [server1].[database].[dbo].[table1]

0

Ich weiß, dass dies eine alte Frage ist, aber ich verwende Synonyme. Angeblich wird die Abfrage auf dem Datenbankserver A ausgeführt und sucht nach einer Tabelle in einem Datenbankserver B, die auf Server A nicht vorhanden ist. Fügen Sie dann ein Synonym für eine Datenbank hinzu, die Ihre Tabelle von Server B aufruft. Ihre Abfrage muss nicht Fügen Sie beliebige Schemas oder andere Datenbanknamen hinzu. Rufen Sie einfach den Tabellennamen wie gewohnt auf, und es funktioniert.

Es ist nicht erforderlich, Server zu verknüpfen, da Synonyme per say eine Art Verknüpfung darstellen.


1
Was ist nun in diesem Zusammenhang ein "Synonym"?
Oskar Berggren

Es ist ein Datenbankobjekt, das auf ein Basisobjekt in einer anderen Datenbank verweist. Weitere Informationen hier: docs.microsoft.com/en-us/sql/relational-databases/synonyms/…
Niklas Henricson

Cool, ich wusste nichts über diese Funktion. Sie geben jedoch auch an, dass kein Verbindungsserver erforderlich ist, aber ich verstehe nicht, wie. Synonyme selbst scheinen genau das zu sein, ein Synonym, und enthalten selbst keine spezifische Remoting-Fähigkeit. In Beispiel B unter docs.microsoft.com/en-us/sql/t-sql/statements/… erstellen sie einen Verbindungsserver, bevor sie ihn von einem Synonym aus referenzieren.
Oskar Berggren

Es stimmt, ich habe angenommen, dass sich die Datenbanken in derselben Serverumgebung befinden. Natürlich müssen Sie Datenbanken immer verknüpfen, wenn sie voneinander entfernt sind. Es gibt keine andere Möglichkeit, mit einer Datenbank-zu-Datenbank-Beziehung darauf zuzugreifen.
Niklas Henricson

0

Serverobjekte ---> Verbindungsserver ---> Neuer Verbindungsserver

Schreiben Sie im Verbindungsserver den Servernamen oder die IP-Adresse für einen anderen Server und wählen Sie SQL Server. Wählen Sie unter Sicherheit die Option (in diesem Sicherheitskontext erstellt). Schreiben Sie die Anmeldung und das Kennwort für einen anderen Server

Jetzt verbunden, dann verwenden

Select * from [server name or ip addresses ].databasename.dbo.tblname

0

Vereinfachte Lösung zum Hinzufügen von Verbindungsservern

Erster Server

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

Zweiter Login

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

Führen Sie Abfragen von einer verknüpften lokalen Datenbank aus

INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.