首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 存取遠端資料庫完整指南:Linked Server、OPENROWSET、OPENDATASOURCE、OPENQUERY

     編輯:關於SqlServer

前置準備:啟用 Ad Hoc Distributed Queries

-- 僅需一次,開啟後建議用畢關閉以減少攻擊面
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'Ad Hoc Distributed Queries', 1; RECONFIGURE;

-- 用畢關閉
EXEC sp_configure 'Ad Hoc Distributed Queries', 0; RECONFIGURE;
EXEC sp_configure 'show advanced options', 0; RECONFIGURE;

四種存取方式對比

方式適用場景效能/快取安全性語法複雜度
Linked Server頻繁、固定遠端存取;支援分散式交易最佳 (計畫快取、統計資料同步)集中管理登入對應初建較繁,後續最簡
OPENQUERY需在遠端執行複雜邏輯、利用遠端索引/統計良好 (遠端編譯)透過 Linked Server 登入中
OPENROWSET臨時、一次性存取;不想建立永久連結一般 (本地編譯)連線字串含密碼風險高 (字串參數多)
OPENDATASOURCE類似 OPENROWSET,語法更簡潔一般同 OPENROWSET中

1. Linked Server 建立與使用

-- 建立
EXEC sp_addlinkedserver 
    @server = 'LNK_PROD', 
    @srvproduct = '', 
    @provider = 'SQLNCLI',  -- SQL 2005+ 建議 SQLNCLI / MSOLEDBSQL
    @datasrc = '192.168.10.50';  -- IP 或主機名

-- 登入對應 (本地登入 → 遠端登入)
EXEC sp_addlinkedsrvlogin 
    @rmtsrvname = 'LNK_PROD', 
    @useself = 'FALSE', 
    @locallogin = NULL,  -- NULL 表所有本地登入
    @rmtuser = 'remote_user', 
    @rmtpassword = 'StrongPassword';

-- 查詢 (四部分命名)
SELECT * FROM [LNK_PROD].[SalesDB].[dbo].[Orders];

-- 匯入
SELECT * INTO LocalOrders FROM [LNK_PROD].[SalesDB].[dbo].[Orders];

-- 更新遠端
UPDATE r SET r.Status = l.Status
FROM [LNK_PROD].[SalesDB].[dbo].[Orders] r
JOIN LocalOrders l ON r.OrderID = l.OrderID;

-- 移除
EXEC sp_dropserver 'LNK_PROD', 'droplogins';

2. OPENROWSET 即時查詢 (免建立 Linked Server)

-- SQLNCLI (SQL 2005+ 推薦)
SELECT * FROM OPENROWSET(
    'SQLNCLI', 
    'Server=192.168.10.50;UID=remote_user;PWD=StrongPassword;', 
    'SELECT OrderID, CustID, Amount FROM SalesDB.dbo.Orders WHERE OrderDate > ''2024-01-01'''
) AS t;

-- 信任連線 (Windows 驗證)
SELECT * FROM OPENROWSET(
    'SQLNCLI', 
    'Server=192.168.10.50;Trusted_Connection=yes;', 
    'SalesDB.dbo.Orders'
) AS t;

-- 匯入/更新/刪除 (需資料來源支援)
INSERT OPENROWSET('SQLNCLI', 'Server=...;Trusted_Connection=yes;', 'SELECT col FROM DB.dbo.T')
SELECT col FROM LocalT;

UPDATE OPENROWSET('SQLNCLI', '...', 'SELECT col FROM DB.dbo.T WHERE id=1')
SET col = 'new';

DELETE FROM OPENROWSET('SQLNCLI', '...', 'SELECT col FROM DB.dbo.T WHERE id=1');

3. OPENQUERY (需先有 Linked Server,遠端執行)

-- 查詢
SELECT * FROM OPENQUERY(LNK_PROD, 'SELECT * FROM SalesDB.dbo.Orders WHERE Amount > 1000');

-- 匯入遠端
INSERT OPENQUERY(LNK_PROD, 'SELECT col FROM SalesDB.dbo.T')
SELECT col FROM LocalT;

-- 更新遠端
UPDATE OPENQUERY(LNK_PROD, 'SELECT col FROM SalesDB.dbo.T WHERE id=1')
SET col = 'new';

4. OPENDATASOURCE (單次連線字串)

SELECT * FROM OPENDATASOURCE(
    'SQLNCLI', 
    'Data Source=192.168.10.50;User ID=remote_user;Password=StrongPassword'
).SalesDB.dbo.Orders;

安全性最佳實務

  • **最小權限**:遠端登入布號僅授予必要資料庫的 `SELECT/INSERT/UPDATE/DELETE`,嚴禁 `sysadmin`/`db_owner`。
  • **避免明文密碼**:優先使用 Windows 驗證 (`Trusted_Connection=yes`) 或 Linked Server 登入對應 (`sp_addlinkedsrvlogin`),勿在程式碼/腳本中硬編碼密碼。
  • **防火牆限制**:遠端 SQL 連接埠 (預設 1433) 僅允許已知應用伺服器 IP 存取。
  • **稽核**:啟用 `LOGON`、`EXECUTE` 稽核追蹤跨伺服器存取。

常見錯誤排查

錯誤原因解決
SQL Server 阻止了對組件 'Ad Hoc Distributed Queries' 的存取未啟用選項執行上述 `sp_configure` 啟用
登入失敗 / 解密過程中出錯 (15466, 15185)服務主金鑰不匹配 / 登入對應遺失`ALTER SERVICE MASTER KEY FORCE REGENERATE;` 重新產生主金鑰,重建登入對應
分散式交易 (MSDTC) 錯誤MSDTC 服務未啟動/防火牆阻擋雙邊啟用 MSDTC、開放 135/動態埠、設定「不需要驗證」/「允許遠端用戶端」
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved