分散式查詢讓 SQL Server 能在單一陳述式中存取多個資料源 (SQL Server、Oracle、ODBC 等) 的資料。本文從系統架構切入,詳細說明「連結伺服器」與「臨時名稱 (OPENROWSET/OPENDATASOURCE)」兩大實作模式,並提供完整配置腳本、權限設定、常見錯誤排查與進階資料搬移技巧。
SQL Server 透過 OLE DB 提供者存取外部資料源。提供者將資料公開為「資料列集」,SQL Server 可在 T-SQL 中像操作本地表一樣引用它。客戶端 → SQL Server → OLE DB Provider → 遠端資料源 (SQL/Oracle/Access/文字檔...)。


| 特性 | 連結伺服器 | OPENROWSET / OPENDATASOURCE |
|---|---|---|
| 持久性 | 永久物件,元資料儲存於 master | 臨時、即時指定,無持久化 |
| 適用場景 | 固定、高頻、大批量跨伺服器存取 | 臨時、探勘性、低頻查詢 |
| 安全性管理 | 集中管理登入映射、權限 | 連接字串內含帳密,風險較高 |
| 效能 | 計畫可重用,連線池優化 | 每次重新解析、建立連線,不適合大量資料 |
| 語法 | sp_addlinkedserver + 四段式命名 | OPENROWSET(provider, conn_str, query) |
EXEC sp_addlinkedserver @server = '192.168.10.104', @srvproduct = 'SQL Server';
-- 驗證
SELECT name, product, provider, data_source FROM sys.servers WHERE is_linked = 1;
-- 清理舊物件
EXEC sp_droplinkedsrvlogin 'demodb', NULL;
EXEC sp_dropserver 'demodb', 'droplogins';
-- 建立連結伺服器
EXEC sp_addlinkedserver
@server = 'demodb',
@srvproduct = '',
@provider = 'SQLOLEDB',
@datasrc = '192.168.10.76';
-- 建立登入映射 (本地登入 -> 遠端帳密)
EXEC sp_addlinkedsrvlogin
@rmtsrvname = 'demodb',
@useself = 'false',
@locallogin = NULL,
@rmtuser = 'Test',
@rmtpassword = 'RemoteDB';
-- 查詢驗證
SELECT * FROM [demodb].CustomerDB.dbo.Users;

EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'Ad Hoc Distributed Queries', 1; RECONFIGURE;
-- OPENDATASOURCE
SELECT * FROM OPENDATASOURCE('SQLOLEDB', 'Data Source=192.168.10.67;User ID=sa;Password=pwd').CustomerDB.dbo.Users;
-- OPENROWSET (支援複雜查詢)
SELECT * FROM OPENROWSET('SQLOLEDB', 'Server=192.168.10.67;UID=sa;PWD=pwd', 'SELECT * FROM CustomerDB.dbo.Users WHERE Id > 100');
-- 遠端資料導入本地 (SELECT INTO)
SELECT * INTO LocalCopyDB FROM [demodb].CustomerDB.dbo.Users;
-- 注意:LocalCopyDB 不會繼承 PK、Index、Constraint
-- 本地資料導入遠端
INSERT INTO [demodb].CustomerDB.dbo.Users SELECT * FROM LocalTable;
-- 跨伺服器 UPDATE
UPDATE b SET b.ColA = a.ColA
FROM OPENROWSET('SQLOLEDB', 'Server=Remote;UID=sa;PWD=pwd', 'SELECT ColA, PK FROM RemoteDB.dbo.RemoteTable') a
INNER JOIN LocalTable b ON a.PK = b.PK;
-- 分散式交易 (需 MSDTC 啟用)
BEGIN DISTRIBUTED TRANSACTION;
INSERT INTO [demodb].DB.dbo.T1 VALUES (...);
INSERT INTO [localdb].DB.dbo.T2 VALUES (...);
COMMIT TRANSACTION;
sys.sysprocesses 找出阻塞 SPID,KILL 使用者進程 (系統進程不可 KILL)。Ad Hoc Distributed Queries 且執行帳號有權限。連結伺服器適合生產環境固定、高頻、需安全管理的跨伺服器存取;OPENROWSET/OPENDATASOURCE 適合開發測試、臨時探勘。掌握 OLE DB 提供者特性、登入映射機制、MSDTC 分散式交易配置,是穩健實作分散式查詢的關鍵。