Chọn dữ liệu từ hai máy chủ khác nhau trong SQL Server


363

Làm cách nào tôi có thể chọn dữ liệu trong cùng một truy vấn từ hai cơ sở dữ liệu khác nhau trên hai máy chủ khác nhau trong SQL Server?


6
Câu trả lời từ Eric và Raging Bull rất tiện dụng. Tôi đã có thể sử dụng điều này để sao chép khối lượng dữ liệu khổng lồ từ DEV sang SẢN PHẨM trong thời gian cắt giảm từ 5 giờ đến 18 giờ, xuống còn 17 giây.
Chris Aldrich

@Eric, danh tiếng để chỉnh sửa một câu hỏi mơ hồ và biến nó thành một câu hỏi 170 câu :)
Eric Wu

Câu trả lời:


345

Những gì bạn đang tìm kiếm là Máy chủ được liên kết. Bạn có thể truy cập chúng trong SSMS từ vị trí sau trong cây của Object Explorer:

Server Objects-->Linked Servers

hoặc bạn có thể sử dụng sp_addlinkbederver .

Bạn chỉ phải thiết lập một. Khi bạn đã có điều đó, bạn có thể gọi một bảng trên máy chủ khác như vậy:

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

Lưu ý rằng chủ sở hữu không phải lúc nào cũng dbovậy, vì vậy hãy đảm bảo thay thế nó bằng bất kỳ lược đồ nào bạn sử dụng.


13
chúng ta có thể làm điều đó mà không cần máy chủ liên kết?
Hấp

5
@Eric, Đối tượng máy chủ ở đâu trong SSMS?
Tsahi Asher

9
@TsahiAsher - Khi bạn kết nối với máy chủ, Đối tượng Máy chủ là một thư mục trong cây của Object Explorer.
Eric

2
Nếu không biết, bạn cũng có thể bỏ qua lược đồ để sử dụng mặc định. Ví dụ: [OtherServerName].[OtherDB]..[OtherTable]tốt nhất là bao gồm nó nếu biết.
Tom Bowers

92

Bạn có thể làm điều đó bằng Máy chủ được liên kết.

Các máy chủ được liên kết thông thường được cấu hình để cho phép Công cụ cơ sở dữ liệu thực thi câu lệnh Transact-SQL bao gồm các bảng trong một phiên bản khác của SQL Server hoặc một sản phẩm cơ sở dữ liệu khác như Oracle. Nhiều loại nguồn dữ liệu OLE DB có thể được cấu hình làm máy chủ được liên kết, bao gồm Microsoft Access và Excel.

Các máy chủ được liên kết cung cấp các lợi thế sau:

  • Khả năng truy cập dữ liệu từ bên ngoài SQL Server.
  • Khả năng đưa ra các truy vấn, cập nhật, lệnh và giao dịch phân tán trên các nguồn dữ liệu không đồng nhất trên toàn doanh nghiệp.
  • Khả năng giải quyết các nguồn dữ liệu đa dạng tương tự nhau.

Tìm hiểu thêm về Máy chủ được liên kết .

Thực hiện theo các bước sau để tạo Máy chủ được liên kết:

  1. Đối tượng máy chủ -> Máy chủ được liên kết -> Máy chủ được liên kết mới

  2. Cung cấp tên máy chủ từ xa.

  3. Chọn Loại máy chủ từ xa (SQL Server hoặc loại khác).

  4. Chọn Bảo mật -> Được thực hiện bằng bối cảnh bảo mật này và cung cấp thông tin đăng nhập và mật khẩu của máy chủ từ xa.

  5. Nhấn OK và bạn đã hoàn thành !!

Đây là một hướng dẫn đơn giản để tạo một máy chủ được liên kết.

HOẶC LÀ

Bạn có thể thêm máy chủ được liên kết bằng truy vấn.

Cú pháp:

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

Tìm hiểu thêm về sp_addlinkbederver .

Bạn phải tạo máy chủ được liên kết chỉ một lần . Sau khi tạo máy chủ được liên kết, chúng ta có thể truy vấn nó như sau:

select * from LinkedServerName.DatabaseName.OwnerName.TableName

Lưu ý: xem ở đây để biết cách đặt tên máy chủ không phải là tên máy chủ / cổng.
Richard

1
Một mẹo nhỏ, ở đây nếu bạn gặp sự cố với sp_addlinkedserver. Tạo máy chủ trong hộp thoại - đảm bảo nó hoạt động - sau đó nhấp chuột phải vào kết nối và chọn tập lệnh [máy chủ được liên kết AS tạo
Richard Housham

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

Bạn cũng có thể xem xét bằng cách sử dụng Máy chủ được liên kết. Các máy chủ được liên kết cũng có thể là các loại nguồn dữ liệu khác, chẳng hạn như các nền tảng DB2. Đây là một phương pháp để cố gắng truy cập DB2 từ cuộc gọi TSQL hoặc Sproc của SQL Server ...


2
phương pháp này sẽ làm việc tất cả các thời gian? các kịch bản mà nó có thể thất bại là gì?
Hấp

3
Xác nhận điều này không thành công trong env của tôi, lỗi nói rằng tôi cần sử dụng addlinkbederver
gorlaz

1
Điều này có hiệu quả với bất cứ ai mà không cần sử dụng Máy chủ được liên kết không?
Doug S

đã kiểm tra và nhận được lỗi là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

22

Truy vấn trên 2 cơ sở dữ liệu khác nhau là một truy vấn phân tán. Dưới đây là danh sách một số kỹ thuật cộng với ưu và nhược điểm:

  1. Máy chủ được liên kết: Cung cấp quyền truy cập vào nhiều nguồn dữ liệu rộng hơn so với sao chép Máy chủ SQL cung cấp
  2. Máy chủ được liên kết: Kết nối với các nguồn dữ liệu sao chép không hỗ trợ hoặc yêu cầu truy cập ad hoc
  3. Máy chủ được liên kết: Hoạt động tốt hơn OPENDATASOURCE hoặc OPENWAYSET
  4. Các chức năng OPENDATASOURCEOPENWAYSET : Thuận tiện cho việc truy xuất dữ liệu từ các nguồn dữ liệu trên cơ sở đặc biệt. OPENWAYSET có các tiện ích BULK cũng có thể / có thể không yêu cầu tệp định dạng có thể là fiddley
  5. OPENQUERY : Không hỗ trợ các biến
  6. Tất cả đều là giải pháp T-SQL. Tương đối dễ thực hiện và thiết lập
  7. Tất cả đều phụ thuộc vào kết nối giữa nguồn và định mệnh có thể ảnh hưởng đến hiệu suất và khả năng mở rộng

OPENQUERY vẫn yêu cầu một máy chủ được liên kết trong đó như OPENDATASOURCE không
CJ

16

thử cái này:

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

Đây đều là những câu trả lời hay, nhưng câu trả lời này còn thiếu và nó có những công dụng mạnh mẽ. Có thể nó không phù hợp với những gì OP muốn, nhưng câu hỏi rất mơ hồ và tôi cảm thấy những người khác có thể tìm đường đến đây. Về cơ bản, bạn có thể sử dụng 1 cửa sổ để chạy đồng thời một truy vấn đối với nhiều máy chủ, dưới đây là:

Trong SSMS mở máy chủ đăng ký và tạo ra một Server Group mới dưới máy chủ nhóm địa phương .

Trong nhóm này tạo Đăng ký máy chủ mới cho mỗi máy chủ bạn muốn truy vấn. Nếu tên DB khác nhau, đảm bảo đặt mặc định cho từng thuộc tính.

Bây giờ hãy quay lại Nhóm bạn đã tạo ở bước đầu tiên, nhấp chuột phải và chọn Truy vấn mới. Một cửa sổ truy vấn mới sẽ mở ra và mọi truy vấn bạn chạy sẽ được thực hiện trên mỗi máy chủ trong nhóm. Các kết quả được trình bày trong một tập dữ liệu duy nhất có tên cột bổ sung cho biết bản ghi đến từ máy chủ nào. Nếu bạn sử dụng thanh trạng thái, bạn sẽ lưu ý tên máy chủ được thay thế bằng nhiều .


2
Điều này dường như giả định rằng truy vấn sử dụng cùng một bảng trên tất cả các cơ sở dữ liệu. (Điều này tốt cho các bảng tiêu chuẩn như sys.tables nhưng không có khả năng cho các bảng được tạo tùy chỉnh như dbo.mycustomers)
Dennis Jaheruddin

Với "cùng một truy vấn từ hai cơ sở dữ liệu khác nhau", rất có thể có cùng một bảng. Nhưng vâng, tôi thường xuyên sử dụng phương pháp này cho một hệ thống sản xuất được đặt trên một số máy chủ và để truy vấn các bảng MSDB.
Paul

Thực sự tính năng mát mẻ. Hạn chế là lược đồ của tập kết quả phải khớp, vì nó thực thi truy vấn hai lần và hợp nhất tất cả chúng cùng một lúc. Sẽ thật tuyệt nếu bạn có thể tham chiếu các máy chủ trong chính SQL, giống như bạn có thể với các máy chủ được liên kết, ngay cả khi bạn không thể THAM GIA bộ kết quả và các bộ phải được xây dựng để được đánh giá riêng.
Kross

1
@Kross bạn sắp xếp có thể. Tạo bảng #output, thực hiện logic dựa trên @@ SERVERNAME và điền dữ liệu vào #output sau đó kết thúc bằng một lựa chọn trên đó. Tôi đã làm một điều tương tự để truy vấn Thông tin nhật ký từ hỗn hợp các máy SQL2000 và SQL2008R2 có các mức thông tin / cột khác nhau, nhưng thay vì @@ SERVERNAME tôi đang sử dụng biến phiên bản máy chủ.
Paul

9

Tôi gặp vấn đề tương tự khi kết nối SQL_server 2008 với SQL_server 2016 được lưu trữ trong một máy chủ từ xa. Những câu trả lời khác không có tác dụng với tôi. Tôi viết giải pháp tinh chỉnh của mình ở đây vì tôi nghĩ nó có thể hữu ích cho người khác.

Một câu trả lời mở rộng cho các kết nối db IP từ xa:

Bước 1: liên kết máy chủ

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'

... Đâu SRV_NAMElà một cái tên được phát minh. Chúng tôi sẽ sử dụng nó để chỉ máy chủ từ xa từ các truy vấn của chúng tôi. aaa.bbb.ccc.dddlà địa chỉ IP của máy chủ từ xa lưu trữ SQLserver DB của bạn.

Bước 2: Chạy truy vấn của bạn Ví dụ:

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

... Và đó là nó!

Chi tiết cú pháp: sp_addlinkedserversp_addlinkedsrvlogin


4

Tạo định nghĩa Máy chủ được liên kết trong một máy chủ này sang máy chủ khác (bạn cần SA để thực hiện việc này), sau đó chỉ cần tham chiếu chúng với cách đặt tên 4 phần (xem BOL).


4

Máy chủ 2008:

Khi ở SSMS được kết nối với server1.DB1 và ​​thử:

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

như những người khác lưu ý, nếu nó không hoạt động thì đó là do máy chủ không được liên kết.

Tôi nhận được lỗi:

Không thể tìm thấy máy chủ DB2 trong sys.servers. Xác minh rằng tên máy chủ chính xác đã được chỉ định. Nếu cần, hãy thực thi thủ tục lưu trữ sp_addlinkbederver để thêm máy chủ vào sys.servers.

Để thêm máy chủ:

tham khảo: Để thêm máy chủ bằng sp_addlinkedserver Liên kết: [1]: Để thêm máy chủ bằng sp_addlinkedserver

Để xem những gì trong sys.servers của bạn, chỉ cần truy vấn nó:

SELECT * FROM [sys].[servers]

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

2

Như @ Super9 đã nói về OPENDATASOURCE bằng cách sử dụng Xác thực máy chủ SQL với nhà cung cấp dữ liệu SQLOLEDB . Tôi chỉ đăng ở đây một đoạn mã cho một bảng nằm trong cơ sở dữ liệu sever hiện tại nơi mã đang chạy và một mã khác trong máy chủ khác '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')

vì vậy nó nên đi như thế này -

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

0

Tôi biết đây là một câu hỏi cũ nhưng tôi sử dụng từ đồng nghĩa. Giả sử truy vấn được thực thi trong máy chủ cơ sở dữ liệu A và tìm bảng trong máy chủ cơ sở dữ liệu B không tồn tại trên máy chủ A. Thêm vào đó một từ đồng nghĩa trên cơ sở dữ liệu gọi bảng của bạn từ máy chủ B. Truy vấn của bạn không phải bao gồm bất kỳ lược đồ hoặc tên cơ sở dữ liệu khác nhau, chỉ cần gọi tên bảng theo thông thường và nó sẽ hoạt động.

Không cần phải liên kết các máy chủ vì các từ đồng nghĩa mỗi lần nói là loại liên kết.


1
Bây giờ sau đó, một "từ đồng nghĩa" trong bối cảnh này là gì?
Oskar Berggren

Đó là một đối tượng cơ sở dữ liệu đề cập đến một đối tượng cơ sở trong cơ sở dữ liệu khác. Thêm thông tin ở đây: docs.microsoft.com/en-us/sql/relational-database/synonymouss/ gợi
Niklas Henricson

Thật tuyệt, tôi không biết về tính năng đó. Tuy nhiên, bạn cũng nói rằng họ tránh sự cần thiết của một máy chủ được liên kết, nhưng tôi không biết làm thế nào. Bản thân các từ đồng nghĩa dường như chỉ là một từ đồng nghĩa chứ không chứa bất kỳ khả năng từ xa cụ thể nào. Trong ví dụ B tại docs.microsoft.com/en-us/sql/t-sql/statements/ , họ tạo một máy chủ được liên kết trước khi tham chiếu nó từ một từ đồng nghĩa.
Oskar Berggren

Đúng, tôi giả sử các cơ sở dữ liệu trong cùng một môi trường máy chủ. Tất nhiên, bạn sẽ luôn phải liên kết cơ sở dữ liệu nếu chúng ở xa nhau. Không có cách nào khác để truy cập với mối quan hệ cơ sở dữ liệu với cơ sở dữ liệu.
Niklas Henricson

0

Đối tượng máy chủ ---> máy chủ được liên kết ---> máy chủ được liên kết mới

Trong máy chủ được liên kết, hãy viết tên máy chủ hoặc địa chỉ IP cho máy chủ khác và chọn SQL Server In Security select (được thực hiện bằng bối cảnh bảo mật này) Viết thông tin đăng nhập và mật khẩu cho máy chủ khác

Bây giờ kết nối rồi sử dụng

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

0

Giải pháp đơn giản hóa để thêm các máy chủ được liên kết

Máy chủ đầu tiên

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

Đăng nhập lần thứ hai

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

Thực hiện các truy vấn từ liên kết đến db cục bộ

INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.