利用 OPENROWSET/OPENDATASOURCE 與 Jet/ACE OLE DB 驅動,SQL Server 可將 Excel 視為關聯數據源,實現無 SSIS/導入導出嚮導的輕量級數據交互。
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'Ad Hoc Distributed Queries', 1; RECONFIGURE;
驅動選擇:
Microsoft.Jet.OLEDB.4.0:僅支援 .xls (Excel 97-2003),32 位進程。Microsoft.ACE.OLEDB.12.0:支援 .xls/.xlsx,需安裝 Access Database Engine(建議 64 位版匹配 SQL Server)。-- .xls 範例
SELECT *
FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
'Data Source="C:\Data\Book1.xls";Extended Properties="Excel 8.0;HDR=YES"')
...[Sheet1$];
-- .xlsx 範例(ACE)
SELECT *
FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0',
'Data Source="C:\Data\Book1.xlsx";Extended Properties="Excel 12.0 Xml;HDR=YES"')
...[Sheet1$];
關鍵參數:HDR=YES 首行作列名;IMEX=1 混合類型列按文本讀取(避免數字列讀空)。
SELECT * INTO dbo.NewTable
FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0',
'Data Source="C:\Data\Book1.xlsx";Extended Properties="Excel 12.0 Xml;HDR=YES"')
...[Sheet1$];
自動推斷列類型,主鍵/索引需後續手動添加。
-- 導出表
EXEC master..xp_cmdshell
'bcp "SELECT Col1, Col2 FROM MyDB.dbo.MyTable" queryout "C:\Export\Data.xlsx" -c -t, -S"ServerName" -U"User" -P"Pwd"';
-- 參數說明:-c 字符模式,-t 分隔符,-S/U/P 連接信息
INSERT INTO OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0',
'Data Source="C:\Export\Template.xlsx";Extended Properties="Excel 12.0 Xml;HDR=YES"')
...[Sheet1$] (Col1, Col2)
SELECT Col1, Col2 FROM MyDB.dbo.MyTable;
限制:目標 Excel 必須預先存在、工作表有表頭、列順序一致,且不支援自動建文件。
INSERT INTO OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0',
'Data Source="C:\Data\Book1.xlsx";Extended Properties="Excel 12.0 Xml;HDR=YES"')
...[Sheet1$] (A1, A2, A3)
VALUES (1, 2, 3);
| 錯誤 | 原因 | 解決 |
|---|---|---|
| 「找不到安裝可用的提供程序」 | 未安裝 ACE 驅動或位數不匹配 | 安裝 64 位 Access Database Engine;SQL Server 32 位則裝 32 位 |
| 「外部表不是預期的格式」 | .xlsx 用 Jet 驅動、或文件損壞 | 改用 ACE;檢查文件完整性 |
| 「Microsoft.ACE.OLEDB.12.0 提供程序未註冊」 | 驅動未註冊 | 以管理員運行 msoledbac.exe 或重裝驅動 |
| 權限錯誤 | SQL Server 服務帳戶無文件讀寫權限 | 授予服務帳戶目錄 NTFS 權限 |
OPENROWSET 快速探查。IMEX=1 強制文本讀取。