執行 SELECT * FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0', 'Excel 5.0;HDR=YES;Database=E:\class.xls', 'Sheet1$') 時出現:
SQL Server 阻止了對組件 'Ad Hoc Distributed Queries' 的 STATEMENT 'OpenRowset/OpenDatasource' 的存取,因為此組件已作為此伺服器安全性組態的一部分而被關閉。系統管理員可以透過使用 sp_configure 啟用 'Ad Hoc Distributed Queries'。
SQL Server 2005+ 預設停用 Ad Hoc Distributed Queries** 進階選項,以減少攻擊面。需明確啟用才能使用 OPENROWSET、OPENDATASOURCE 進行臨時分散式查詢。
-- 1. 顯示進階選項
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
-- 2. 啟用 Ad Hoc Distributed Queries
EXEC sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
-- 1. 關閉 Ad Hoc Distributed Queries
EXEC sp_configure 'Ad Hoc Distributed Queries', 0;
RECONFIGURE;
-- 2. 隱藏進階選項
EXEC sp_configure 'show advanced options', 0;
RECONFIGURE;
EXEC sp_configure 'Ad Hoc Distributed Queries';
-- run_value = 1 表示啟用,0 表示停用
若頻繁存取同一外部資料源,建議建立 連結伺服器,不需啟用 Ad Hoc 選項:
EXEC sp_addlinkedserver
@server = 'ExcelData',
@srvproduct = 'ACE',
@provider = 'Microsoft.ACE.OLEDB.12.0',
@datasrc = 'E:\class.xlsx',
@provstr = 'Excel 12.0;HDR=YES';
-- 查詢
SELECT * FROM OPENQUERY(ExcelData, 'SELECT * FROM [Sheet1$]');
優點:權限可精細控制 (只授予特定登入存取連結伺服器)、連線字串集中管理、不需開放 Ad Hoc 風險。
| 資料源 | Provider | 連接字串範例 |
|---|---|---|
| Excel 97-2003 (.xls) | Microsoft.Jet.OLEDB.4.0 | Excel 5.0;HDR=YES;Database=path.xls |
| Excel 2007+ (.xlsx) | Microsoft.ACE.OLEDB.12.0 | Excel 12.0;HDR=YES;Database=path.xlsx |
| Access (.mdb) | Microsoft.Jet.OLEDB.4.0 | Database=path.mdb;User ID=admin;Password=; |
| Access (.accdb) | Microsoft.ACE.OLEDB.12.0 | Database=path.accdb;User ID=admin;Password=; |
| CSV 文字檔 | Microsoft.Jet.OLEDB.4.0 | Text;HDR=YES;Database=folder_path |
Ad Hoc Distributed Queries 是便利與風險的雙面刃。臨時查詢可短暫啟用;長期存取請採連結伺服器或 ETL 流程,落實最小權限與最小攻擊面原則。