Memilih data dari dua server berbeda di SQL Server


363

Bagaimana saya bisa memilih data dalam kueri yang sama dari dua database berbeda yang ada di dua server berbeda di SQL Server?


6
Jawaban dari Eric dan Raging Bull sangat berguna. Saya dapat menggunakan ini untuk menyalin volume data massal dari DEV ke PROD dengan mengurangi waktu mulai dari 5 jam hingga 18 jam, turun menjadi 17 detik.
Chris Aldrich

@Eric, pujian untuk mengedit pertanyaan yang agak ambigu dan menjadikannya pertanyaan 170-rep :)
Eric Wu

Jawaban:


345

Apa yang Anda cari adalah Server Tertaut. Anda bisa mendapatkannya di SSMS dari lokasi berikut di bagan Object Explorer:

Server Objects-->Linked Servers

atau Anda dapat menggunakan sp_addlinkedserver .

Anda hanya perlu mengatur satu. Setelah memilikinya, Anda dapat memanggil tabel di server lain seperti:

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

Perhatikan bahwa pemiliknya tidak selalu dbo, jadi pastikan untuk menggantinya dengan skema apa pun yang Anda gunakan.


13
dapatkah kita melakukannya tanpa server yang ditautkan?
Uap

5
@ Eric, Di mana Objek Server di SSMS?
Tsahi Asher

9
@TsahiAsher - Ketika Anda terhubung ke server, Server Objects adalah folder di pohon dari Object Explorer.
Eric

2
Jika tidak diketahui, Anda juga bisa menghilangkan skema untuk menggunakan default. Misalnya [OtherServerName].[OtherDB]..[OtherTable]Namun yang terbaik adalah memasukkannya jika diketahui.
Tom Bowers

92

Anda dapat melakukannya menggunakan Linked Server.

Server yang tertaut secara tipikal dikonfigurasikan untuk mengaktifkan Database Engine untuk mengeksekusi pernyataan Transact-SQL yang menyertakan tabel dalam contoh lain dari SQL Server, atau produk database lain seperti Oracle. Banyak jenis sumber data OLE DB dapat dikonfigurasi sebagai server yang ditautkan, termasuk Microsoft Access dan Excel.

Server tertaut menawarkan keuntungan berikut:

  • Kemampuan untuk mengakses data dari luar SQL Server.
  • Kemampuan untuk mengeluarkan kueri terdistribusi, pembaruan, perintah, dan transaksi pada sumber data yang heterogen di seluruh perusahaan.
  • Kemampuan untuk mengatasi sumber data yang beragam sama.

Baca lebih lanjut tentang Server Tertaut .

Ikuti langkah-langkah ini untuk membuat Server Tertaut:

  1. Objek Server -> Server Tertaut -> Server Tertaut Baru

  2. Berikan Nama Server Jarak Jauh.

  3. Pilih Jenis Server Jarak Jauh (SQL Server atau Lainnya).

  4. Pilih Keamanan -> Dibuat menggunakan konteks keamanan ini dan berikan login dan kata sandi server jarak jauh.

  5. Klik OK dan Anda selesai !!

Berikut ini adalah tutorial sederhana untuk membuat server tertaut.

ATAU

Anda dapat menambahkan server tertaut menggunakan kueri.

Sintaksis:

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

Baca lebih lanjut tentang sp_addlinkedserver .

Anda harus membuat server tertaut hanya sekali . Setelah membuat server tertaut, kami dapat menanyakannya sebagai berikut:

select * from LinkedServerName.DatabaseName.OwnerName.TableName

Catatan: lihat di sini untuk mengetahui cara membuat nama server selain dari nama host / port.
Richard

1
Sedikit tip, di sini jika Anda mengalami masalah dengan sp_addlinkedserver. Buat server dalam dialog - pastikan itu berfungsi - lalu klik kanan koneksi dan pilih skrip [t linked server AS buat
Richard Housham

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

Anda juga dapat melihat menggunakan Server Tertaut. Server yang ditautkan dapat berupa jenis sumber data lain juga seperti platform DB2. Ini adalah salah satu metode untuk mencoba mengakses DB2 dari SQL Server TSQL atau panggilan Sproc ...


2
akankah metode ini bekerja sepanjang waktu? apa skenario di mana ia bisa gagal?
Uap

3
Mengonfirmasi ini gagal dalam env saya, kesalahan mengatakan saya perlu menggunakan addlinkedserver
gorlaz

1
Apakah ini bekerja untuk siapa saja, tanpa menggunakan Server Linked?
Doug S

diuji dan kesalahan yang diterima adalahCould 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

Permintaan di 2 basis data yang berbeda adalah kueri yang didistribusikan. Berikut adalah daftar beberapa teknik ditambah pro dan kontra:

  1. Linked server: Memberikan akses ke berbagai sumber data yang lebih luas daripada replikasi SQL Server
  2. Server tertaut: Terhubung dengan sumber data yang tidak didukung replikasi atau yang memerlukan akses ad hoc
  3. Server tertaut: Berkinerja lebih baik daripada OPENDATASOURCE atau OPENROWSET
  4. Fungsi OPENDATASOURCE dan OPENROWSET : Nyaman untuk mengambil data dari sumber data secara ad hoc. OPENROWSET memiliki fasilitas BULK juga yang mungkin / mungkin tidak memerlukan file format yang mungkin fiddley
  5. OPENQUERY : Tidak mendukung variabel
  6. Semua adalah solusi T-SQL. Relatif mudah diimplementasikan dan diatur
  7. Semua tergantung pada koneksi antara sumber dan destionasi yang dapat mempengaruhi kinerja dan skalabilitas

OPENQUERY masih memerlukan server yang ditautkan di mana OPENDATASOURCE tidak
CJ

16

coba ini:

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

Ini semua adalah jawaban yang baik, tetapi yang ini hilang dan memiliki kegunaan yang kuat. Mungkin itu tidak sesuai dengan yang diinginkan OP, tetapi pertanyaannya tidak jelas dan saya merasa orang lain mungkin menemukan jalan mereka di sini. Pada dasarnya Anda dapat menggunakan 1 jendela untuk secara bersamaan menjalankan kueri terhadap beberapa server, berikut caranya:

Dalam SSMS, buka Server Terdaftar dan buat Grup Server Baru di bawah Grup Server Lokal .

Di bawah grup ini buat Registrasi Server Baru untuk setiap server yang ingin Anda query. Jika nama-nama DB berbeda pastikan untuk menetapkan default untuk masing-masing di properti.

Sekarang kembali ke Grup yang Anda buat di langkah pertama, klik kanan dan pilih Permintaan Baru. Jendela permintaan baru akan terbuka dan permintaan apa pun yang Anda jalankan akan dijalankan pada setiap server dalam grup. Hasilnya disajikan dalam satu set data tunggal dengan nama kolom tambahan yang menunjukkan dari server mana catatan itu berasal. Jika Anda menggunakan bilah status, Anda akan perhatikan bahwa nama server diganti dengan banyak .


2
Ini tampaknya mengasumsikan bahwa kueri menggunakan tabel yang sama di semua database. (Yang bagus untuk tabel standar seperti sys.tables tetapi tidak mungkin untuk tabel yang dibuat khusus seperti dbo.mycustomers)
Dennis Jaheruddin

Mengingat itu "permintaan yang sama dari dua basis data yang berbeda", kemungkinan besar memiliki tabel yang sama. Tapi ya saya secara rutin menggunakan metode ini untuk sistem produksi yang ditempatkan di beberapa server dan untuk query tabel MSDB.
Paul

Fitur yang sangat keren sebenarnya. Kekurangannya adalah skema set hasil harus cocok, karena itu mengeksekusi permintaan dua kali dan menggabungkan mereka semua pada saat yang sama. Akan lebih bagus jika Anda bisa mereferensikan server dalam SQL itu sendiri, seperti yang Anda bisa dengan server yang ditautkan, bahkan jika Anda tidak bisa BERGABUNG dengan set hasil dan set harus dibangun untuk dievaluasi secara terpisah.
Kross

1
@Kross Anda semacam bisa. Buat tabel #output, lakukan logika berdasarkan @@ SERVERNAME dan isi data ke #output lalu akhiri dengan memilihnya. Saya melakukan hal serupa untuk menanyakan info Log dari campuran mesin SQL2000 dan SQL2008R2 yang memiliki level / kolom informasi berbeda, tetapi alih-alih @@ SERVERNAME saya menggunakan variabel versi server.
Paul

9

Saya memiliki masalah yang sama untuk menghubungkan SQL_server 2008 ke SQL_server 2016 yang di-host di server jauh. Jawaban lain tidak langsung bagi saya. Saya menulis solusi tweak saya di sini karena saya pikir ini mungkin berguna untuk orang lain.

Jawaban yang diperluas untuk koneksi IP db jarak jauh:

Langkah 1: tautan 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'

... di mana SRV_NAMEnama ditemukan. Kami akan menggunakannya untuk merujuk ke server jarak jauh dari pertanyaan kami. aaa.bbb.ccc.dddadalah alamat ip dari server jauh yang menghosting SQLserver DB Anda.

Langkah 2: Jalankan pertanyaan Anda Misalnya:

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

... dan itu saja!

Detail sintaks: sp_addlinkedserver dan sp_addlinkedsrvlogin


4

Membuat definisi Linked Server di satu server dengan yang lain (Anda perlu SA untuk melakukan ini), lalu rujuk saja dengan penamaan 4-bagian (lihat BOL).


4

Server 2008:

Ketika di SSMS terhubung ke server1.DB1 dan coba:

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

seperti yang dicatat orang lain, jika tidak berhasil itu karena server tidak terhubung.

Saya mendapatkan kesalahan:

Tidak dapat menemukan server DB2 di sys.servers. Pastikan nama server yang benar telah ditentukan. Jika perlu, jalankan prosedur tersimpan sp_addlinkedserver untuk menambahkan server ke sys.servers.

Untuk menambah server:

referensi: Untuk menambah server menggunakan sp_addlinkedserver Tautan: [1]: Untuk menambahkan server menggunakan sp_addlinkedserver

Untuk melihat apa yang ada di sys.servers Anda cukup kueri itu:

SELECT * FROM [sys].[servers]

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

2

Seperti @ Super9 diceritakan tentang OPENDATASOURCE menggunakan SQL Server Authentication dengan penyedia data SQLOLEDB . Saya hanya memposting di sini potongan kode untuk satu tabel dalam database saat ini tempat kode berjalan dan yang lain di server lain '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')

jadi harus seperti ini -

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

0

Saya tahu ini adalah pertanyaan lama tetapi saya menggunakan sinonim. Seharusnya kueri dijalankan di dalam server database A, dan mencari tabel di server database B yang tidak ada di server A. Tambahkan kemudian sinonim pada database yang memanggil tabel Anda dari server B. Permintaan Anda tidak harus sertakan skema apa pun, atau nama database yang berbeda, cukup panggil nama tabel seperti biasa dan itu akan berfungsi.

Tidak perlu menautkan server karena sinonim per katakan adalah semacam tautan.


1
Nah, apa itu "sinonim" dalam konteks ini?
Oskar Berggren

Ini adalah objek basis data yang merujuk ke objek dasar di basis data lain. Info lebih lanjut di sini: docs.microsoft.com/en-us/sql/relational-databases/synonymous/…
Niklas Henricson

Keren, saya tidak tahu tentang fitur itu. Namun, Anda juga menyatakan mereka menghindari perlunya server yang ditautkan, tetapi saya gagal melihat caranya. Sinonim itu sendiri tampaknya hanya itu, sinonim, dan tidak sendiri mengandung kemampuan remoting tertentu. Dalam contoh B di docs.microsoft.com/en-us/sql/t-sql/statements/… , mereka membuat server tertaut sebelum merujuknya dari sinonim.
Oskar Berggren

Benar, saya berasumsi database berada di lingkungan server yang sama. Tentu saja Anda harus selalu menautkan basis data jika mereka jauh satu sama lain. Tidak ada cara lain untuk mengakses dengan hubungan database-ke-database.
Niklas Henricson

0

Objek Server ---> server tertaut ---> server tertaut baru

Di server yang terhubung tulis nama server atau alamat IP untuk server lain dan pilih SQL Server Di Keamanan pilih (dibuat menggunakan konteks keamanan ini) Tulis login dan kata sandi untuk server lain

Sekarang terhubung lalu gunakan

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

0

Solusi yang disederhanakan untuk menambahkan server yang ditautkan

Server pertama

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

Login Kedua

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

Jalankan permintaan dari yang ditautkan ke db lokal

INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.