Selezione di dati da due server diversi in SQL Server


363

Come posso selezionare i dati nella stessa query da due database diversi che si trovano su due server diversi in SQL Server?


6
Le risposte di Eric e Raging Bull sono molto utili. Sono stato in grado di utilizzare questo per copiare grandi volumi di dati da DEV a PROD riducendo i tempi da 5 ore a 18 ore, fino a 17 secondi.
Chris Aldrich,

@Eric, complimenti per aver modificato una domanda marginalmente ambigua e averla resa una domanda da 170 ripetizioni :)
Eric Wu

Risposte:


345

Quello che stai cercando sono i server collegati. Puoi accedervi in ​​SSMS dalla seguente posizione nella struttura di Esplora oggetti:

Server Objects-->Linked Servers

oppure puoi usare sp_addlinkedserver .

Devi solo crearne uno. Una volta che hai quello, puoi chiamare un tavolo sull'altro server in questo modo:

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

Nota che il proprietario non è sempre dbo, quindi assicurati di sostituirlo con qualunque schema tu usi.


13
possiamo farlo senza server collegati?
Steam

5
@Eric, dove si trovano gli oggetti server in SSMS?
Tsahi Asher,

9
@TsahiAsher - Quando ci si connette a un server, Server Objects è una cartella nella struttura di Esplora oggetti.
Eric,

2
Se non noto, è anche possibile omettere lo schema per utilizzare l'impostazione predefinita. Ad esempio, [OtherServerName].[OtherDB]..[OtherTable]tuttavia, è meglio includerlo se noto.
Tom Bowers,

92

Puoi farlo utilizzando il server collegato.

I server tipicamente collegati sono configurati per consentire al Motore di database di eseguire un'istruzione Transact-SQL che include le tabelle in un'altra istanza di SQL Server o un altro prodotto di database come Oracle. Molte origini dati OLE DB possono essere configurate come server collegati, inclusi Microsoft Access ed Excel.

I server collegati offrono i seguenti vantaggi:

  • La possibilità di accedere ai dati dall'esterno di SQL Server.
  • La capacità di inviare query distribuite, aggiornamenti, comandi e transazioni su origini dati eterogenee in tutta l'azienda.
  • La capacità di affrontare diverse fonti di dati in modo simile.

Per saperne di più server collegati .

Attenersi alla seguente procedura per creare un server collegato:

  1. Oggetti server -> Server collegati -> Nuovo server collegato

  2. Fornire il nome del server remoto.

  3. Selezionare il tipo di server remoto (SQL Server o altro).

  4. Selezionare Sicurezza -> Effettuare utilizzando questo contesto di sicurezza e fornire login e password del server remoto.

  5. Fai clic su OK e hai finito !!

Qui un semplice tutorial per creare un server collegato.

O

È possibile aggiungere un server collegato tramite query.

Sintassi:

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

Ulteriori informazioni su sp_addlinkedserver .

Devi creare un server collegato solo una volta . Dopo aver creato il server collegato, possiamo interrogarlo come segue:

select * from LinkedServerName.DatabaseName.OwnerName.TableName

Nota: vedere qui per sapere come fare in modo che il nome del server sia diverso dal nome host / porta.
Richard,

1
Un piccolo suggerimento, qui se hai problemi con sp_addlinkedserver. Crea il server nella finestra di dialogo - assicurati che funzioni - quindi fai clic con il pulsante destro del mouse sulla connessione e seleziona lo scrip [server collegato come creare
Richard Housham

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

Puoi anche guardare usando i server collegati. I server collegati possono essere anche altri tipi di origini dati come le piattaforme DB2. Questo è un metodo per tentare di accedere a DB2 da una chiamata SQL Server TSQL o Sproc ...


2
questo metodo funzionerà continuamente? quali sono gli scenari in cui potrebbe fallire?
Steam

3
Confermato che questo non riesce nel mio ambiente, l'errore dice che dovevo usare addlinkedserver
gorlaz

1
Funziona con chiunque, senza usare un server collegato?
Doug S,

testato e l'errore ricevuto èCould 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 l'

22

La query su 2 database diversi è una query distribuita. Ecco un elenco di alcune tecniche più i pro ei contro:

  1. Server collegati: forniscono l'accesso a una più ampia varietà di origini dati rispetto alla replica di SQL Server
  2. Server collegati: connettersi con origini dati che la replica non supporta o che richiedono l'accesso ad hoc
  3. Server collegati: prestazioni migliori di OPENDATASOURCE o OPENROWSET
  4. OPENDATASOURCE e OPENROWSET : convenienti per il recupero di dati da origini dati su una base ad hoc. OPENROWSET ha anche BULK facilities che potrebbero / potrebbero non richiedere un file di formato che potrebbe essere mediocre
  5. OPENQUERY : non supporta variabili
  6. Tutti sono soluzioni T-SQL. Relativamente facile da implementare e configurare
  7. Tutti dipendono dalla connessione tra origine e destinazione che potrebbe influire sulle prestazioni e sulla scalabilità

OPENQUERY richiede ancora un server collegato dove OPENDATASOURCE non lo fa
CJ

16

prova questo:

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

Queste sono tutte ottime risposte, ma questa manca e ha i suoi usi potenti. Forse non si adattava a ciò che voleva l'OP, ma la domanda era vaga e sento che altri potrebbero trovare la loro strada qui. Fondamentalmente puoi usare 1 finestra per eseguire contemporaneamente una query su più server, ecco come:

In SSMS aprire Server registrati e creare un nuovo gruppo di server in server locale Gruppi .

Sotto questo gruppo creare la Registrazione nuovo server per ciascun server che si desidera interrogare. Se i nomi dei DB sono diversi, assicurarsi di impostare un valore predefinito per ciascuno nelle proprietà.

Ora torna al gruppo creato nel primo passaggio, fai clic con il pulsante destro del mouse e seleziona Nuova query. Si aprirà una nuova finestra di query e qualsiasi query eseguita verrà eseguita su ciascun server del gruppo. I risultati sono presentati in un singolo set di dati con un nome di colonna aggiuntivo che indica da quale server proviene il record. Se si utilizza la barra di stato, si noterà che il nome del server viene sostituito con più .


2
Ciò sembra presupporre che la query utilizzi le stesse tabelle su tutti i database. (Il che va bene per tavoli standard come sys.tables ma non è probabile per tavoli personalizzati come dbo.mycustomers)
Dennis Jaheruddin,

Dato che è "la stessa query da due database diversi" è molto probabile che abbia le stesse tabelle. Ma sì, uso abitualmente questo metodo per un sistema di produzione ospitato su più server e per interrogare tabelle MSDB.
Paul,

Funzionalità davvero interessante in realtà. Lo svantaggio è che lo schema del set di risultati deve corrispondere, poiché esegue la query due volte e le unisce tutte contemporaneamente. Sarebbe bello se potessi fare riferimento ai server all'interno dello stesso SQL, come puoi fare con i server collegati, anche se non potessi unirti al set di risultati e i set dovessero essere costruiti per essere valutati separatamente.
Kross,

1
@Kross che potresti. Crea una tabella #output, esegui la logica in base a @@ SERVERNAME e popola i dati in #output, quindi finisci con una selezione su quello. Ho fatto una cosa simile per l'interrogazione delle informazioni di registro da un mix di macchine SQL2000 e SQL2008R2 che avevano livelli / colonne di informazioni diverse, ma invece di @@ SERVERNAME stavo usando una variabile di versione del server.
Paolo

9

Ho avuto lo stesso problema per connettere un SQL_server 2008 a un SQL_server 2016 ospitato in un server remoto. Altre risposte non hanno funzionato per me in modo diretto. Scrivo qui la mia soluzione ottimizzata poiché penso possa essere utile per qualcun altro.

Una risposta estesa per le connessioni db IP remote:

Passaggio 1: collegare i server

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'

... dov'è SRV_NAMEun nome inventato. Lo useremo per fare riferimento al server remoto dalle nostre query.aaa.bbb.ccc.dddè l'indirizzo IP del server remoto che ospita il tuo DB SQL Server.

Passaggio 2: eseguire le query Ad esempio:

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

... e basta!

Dettagli della sintassi: sp_addlinkedserver e sp_addlinkedsrvlogin


4

Ha creato una definizione di server collegato in un server all'altro (per farlo è necessario SA), quindi fai semplicemente riferimento a questi con nomi in 4 parti (vedi BOL).


4

Server 2008:

Quando sei in SSMS connesso a server1.DB1 e prova:

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

come altri hanno notato, se non funziona è perché il server non è collegato.

Ottengo l'errore:

Impossibile trovare il server DB2 in sys.servers. Verificare che sia stato specificato il nome del server corretto. Se necessario, eseguire la procedura memorizzata sp_addlinkedserver per aggiungere il server a sys.servers.

Per aggiungere il server:

riferimento: per aggiungere il server usando sp_addlinkedserver Link: [1]: per aggiungere un server usando sp_addlinkedserver

Per vedere cosa c'è nei tuoi server sys basta interrogarlo:

SELECT * FROM [sys].[servers]

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

2

Come @ Super9 ha raccontato di OPENDATASOURCE utilizzando l'autenticazione di SQL Server con il fornitore di dati SQLOLEDB . Sto solo postando qui uno snippet di codice per una tabella nell'attuale database sever in cui il codice è in esecuzione e un altro nell'altro 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')

quindi dovrebbe andare così -

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

0

So che questa è una vecchia domanda, ma uso i sinonimi. Presumibilmente la query viene eseguita all'interno del server di database A e cerca una tabella in un server di database B che non esiste sul server A. Aggiungi quindi un sinonimo su un database che chiama la tabella dal server B. La tua query non deve includere eventuali schemi o nomi di database diversi, basta chiamare il nome della tabella come al solito e funzionerà.

Non è necessario collegare i server in quanto i sinonimi per dire sono una specie di collegamento.


1
Allora, cos'è un "sinonimo" in questo contesto?
Oskar Berggren,

È un oggetto database che fa riferimento a un oggetto base in un altro database. Maggiori informazioni qui: docs.microsoft.com/en-us/sql/relational-d database
Niklas Henricson

Fantastico, non sapevo di quella caratteristica. Tuttavia, affermi anche che evitano la necessità di un server collegato, ma non riesco a vedere come. I sinonimi stessi sembrano essere proprio questo, un sinonimo, e non contengono in sé alcuna specifica capacità di remoting. Nell'esempio B in docs.microsoft.com/en-us/sql/t-sql/statements/… , creano un server collegato prima di fare riferimento a un sinonimo.
Oskar Berggren,

È vero, supponevo che i database si trovassero nello stesso ambiente server. Ovviamente dovrai sempre collegare i database se sono distanti tra loro. Non c'è altro modo di accedere con una relazione database-database.
Niklas Henricson

0

Oggetti server ---> server collegato ---> nuovo server collegato

Nel server collegato scrivere il nome del server o l'indirizzo IP per l'altro server e selezionare SQL Server In Security selezionare (essere effettuato utilizzando questo contesto di sicurezza) Scrivere login e password per l'altro server

Ora connesso, quindi utilizza

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

0

Soluzione semplificata per l'aggiunta di server collegati

Primo server

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

Secondo accesso

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

Eseguire query da collegate a db locali

INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.