核心連接字符串模式
| 目標 | Provider | 關鍵屬性 |
| SQL Server (OLE DB) | SQLOLEDB.1 | Data Source=Server;Initial Catalog=DB;User ID=sa;Password=***;Persist Security Info=True |
| SQL Server (ODBC) | MSDASQL | Driver={SQL Server};Server=127.0.0.1;Database=DB;UID=sa;PWD=*** |
| Excel 97-2003 | Microsoft.Jet.OLEDB.4.0 | Data Source=Path\File.xls;Extended Properties="Excel 8.0;HDR=YES;IMEX=1" |
| Excel 2007+ | Microsoft.ACE.OLEDB.12.0 | Data Source=Path\File.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1" |
| VFP / dBase | Microsoft.Jet.OLEDB.4.0 | Data Source=Path\Folder;Extended Properties="dBASE 5.0" |
四大經典互導模式(以 SQL Server 為中心)
1. SQL Server → Excel (SELECT ... INTO)
-- ADO Connection: Excel (Jet/ACE)
cn.Execute "SELECT * INTO [SheetName$] FROM [ODBC;Driver={SQL Server};Server=127.0.0.1;Database=kcsoft_his;UID=sa;PWD=kcsoft58].[dbo].[drug_yk]";
-- 註:[SheetName$] 為 Excel 工作表名,$ 結尾;目標表不存在時自動創建。
2. SQL Server → Excel (增量追加 INSERT INTO)
cn.Execute "INSERT INTO [SheetName$] SELECT * FROM [ODBC;Driver={SQL Server};Server=127.0.0.1;Database=kcsoft_his;UID=sa;PWD=kcsoft58].[dbo].[drug_yk]";
-- 重複執行會疊加數據,需配合主鍵去重或預先清空。
3. Excel → SQL Server (OPENDATASOURCE / OPENROWSET)
-- ADO Connection: SQL Server (SQLOLEDB)
cn.Execute "SELECT * INTO dbo.Import_Tmp FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0', 'Data Source=""C:\Data\Source.xlsx"";Extended Properties=""Excel 12.0 Xml;HDR=YES""')...[Sheet1$]";
-- 或使用分布式查詢(需啟用 Ad Hoc Distributed Queries):
-- SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;Database=C:\Data\Source.xlsx;HDR=YES', 'SELECT * FROM [Sheet1$]');
4. SQL Server ↔ VFP (dBASE 5.0)
-- SQL Server → VFP (導出 DBF)
cnVfp.Execute "SELECT * INTO [Abc.dbf] FROM [ODBC;Driver={SQL Server};Server=127.0.0.1;Database=kcsoft_his;UID=sa;PWD=kcsoft58].[dbo].[drug_yk]";
-- VFP → SQL Server (導入)
cnSql.Execute "SELECT * INTO dbo.Vfp_Import FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0', 'Data Source=""C:\Data\VfpFolder"";Extended Properties=""dBASE 5.0""')...[Abc]";
工程化封裝建議
通用導入導出類
public class HeteroDataPorter
{
private readonly string _sqlConnStr;
public HeteroDataPorter(string sqlConnStr) => _sqlConnStr = sqlConnStr;
// SQL Server → 平面文件
public void ExportToFlatFile(string sqlQuery, string provider, string extProps, string targetPath, string targetTable)
{
using var dest = new OleDbConnection($@"Provider={provider};Data Source={targetPath};Extended Properties={extProps}");
dest.Open();
using var src = new SqlConnection(_sqlConnStr);
src.Open();
using var cmd = new SqlCommand(sqlQuery, src);
using var reader = cmd.ExecuteReader();
// 批量寫入目標(OleDbCommand + 参数化 或 SqlBulkCopy 反向不適用,這裡簡單演示逐行)
// 實際建議:生成中間 CSV/Parquet 再用目標引擎 BULK INSERT
}
// 平面文件 → SQL Server (OPENROWSET)
public void ImportFromFlatFile(string provider, string extProps, string sourcePath, string sourceSheet, string targetTable)
{
var sql = $@"SELECT * INTO {targetTable} FROM OPENDATASOURCE('{provider}', '{extProps}')...[{sourceSheet}]";
using var cn = new SqlConnection(_sqlConnStr);
cn.Open();
new SqlCommand(sql, cn).ExecuteNonQuery();
}
}
避坑指南
- IMEX=1:Excel 混合類型列強制文本模式,避免數值列前幾行為空導致類型推斷錯誤。
- 64 位環境:必須安裝 64 位 Microsoft Access Database Engine (ACE.OLEDB.12.0/16.0),Jet.OLEDB.4.0 無 64 位版本。
- Ad Hoc Distributed Queries:
sp_configure 'Ad Hoc Distributed Queries', 1; RECONFIGURE; 方可使用 OPENROWSET/OPENDATASOURCE。
- 列名包含空格/關鍵字:Excel/VFP 列名用
[Column Name] 括起。
- 大文件性能:超 10 萬行建議中轉 CSV +
BULK INSERT / bcp / SqlBulkCopy,避免 OLE DB 驅動內存暴漲。
- 事務一致性:跨異構源無分布式事務,採用「暫存表 → 校驗 → 切換/合併」模式。
現代化替代方案
| 場景 | 推薦工具/技術 | 優勢 |
| 定時 ETL | SSIS / Azure Data Factory / Airflow | 可視化、監控、重試、增量捕獲 (CDC) |
| 一次性遷移 | SQL Server Migration Assistant (SSMA) / DBeaver / DataGrip | 異構遷移向導、類型映射、並行傳輸 |
| 應用集成 | Entity Framework Core + 多 Provider / Dapper + 原生驅動 | 強類型、參數化、連接池、異步 |
| 大數據分析 | PolyBase / OPENROWSET (Parquet/CSV/Delta Lake) → Synapse / Spark | 下推計算、列式壓縮、無需落地 |
ADO 互導代碼模式雖屬經典,但在「無驅動安裝權限、臨時腳本、輕量級工具」場景下依然實用。掌握連接字符串、分布式查詢語法、類型映射陷阱,能讓你在沒有重型 ETL 平台時也能快速完成異構數據搬運。