OPENROWSET/OPENDATASOURCE 連結伺服器方式。核心邏輯:
Recordset (SQL Server,adOpenForwardOnly、adLockReadOnly,唯讀游標)。Recordset (Access,adOpenStatic、adLockOptimistic,可更新游標)。AddNew()Fields 集合,按**序數索引** GetCollect(i) / PutCollect(i) 搬運值 (自動處理型別轉換、NULL)。Update() 提交。MoveNext() 直到 EOF。// 假設 m_pRecordset_sql (來源) 和 m_pRecordset_access (目標) 已成功 Open
_variant_t vValue;
while (!m_pRecordset_sql->adoEOF)
{
m_pRecordset_access->AddNew();
for (long i = 0; i < m_pRecordset_sql->Fields->Count; i++)
{
// 按序數獲取值 (自動處理型別、NULL)
vValue = m_pRecordset_sql->GetCollect(_variant_t(i));
// 按序數寫入值
m_pRecordset_access->PutCollect(_variant_t(i), vValue);
}
m_pRecordset_access->Update();
m_pRecordset_sql->MoveNext();
}
| 技術點 | 說明 |
|---|---|
GetCollect / PutCollect | ADO 高效存取欄位值方法,**按序數 (0-based) 而非名稱**,避免名稱不匹配/大小寫問題,效能優於 Fields["Name"]->Value。 |
_variant_t | ATL 智慧型別包裝器,自動管理 VARIANT 參考計數與型別轉換 (SQL datetime ↔ Access Date 等)。 |
| 游標類型選擇 | 來源 adOpenForwardOnly (單向唯讀,最輕量);目標 adOpenStatic / adOpenKeyset + adLockOptimistic (支援 AddNew/Update)。 |
| 批次提交優化 | 大量資料 (萬行+) 建議每 100-500 行 UpdateBatch 或事務包裹,減少往返開銷。 |
| 異構型別映射 | ADO/OLEDB Provider 自動處理常見型別對應 (int↔Long, varchar↔Text, datetime↔Date, bit↔Yes/No)。特殊型別 (image/varbinary) 需分塊寫入。 |
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 雙 Recordset 循環 (本文) | 通用、不需同機、代碼簡潔、自動型別映射 | 逐行往返、大量資料慢 (需批次優化) | 中小表、異機、結構同、一次性/低頻 |
| SSIS 封裝 | 視覺化、高效能、錯誤處理、可排程 | 部署複雜、學習曲線 | 生產級 ETL、大量資料、定期同步 |
| BCP OUT + Access 匯入 | 極快、命令列自動化 | 需中間檔案、型別映射手工處理 | 大表、純資料、可容忍中間檔 |
| Linked Server (OPENROWSET) | 單條 SQL 完成、T-SQL 原生 | **需同機/網路可達**、配置繁瑣、權限敏感 | 同網域、頻繁跨庫查詢/寫入 |
CHECKSUM 聚合比對、抽樣人工複核。當 Access 與 SQL Server 異機且表結構一致時,**ADO 雙 Recordset 循環搬運** 是最輕量、通用的程式化方案。關鍵在於 GetCollect/PutCollect 按序數無感知搬運與游標類型正確選擇。大量資料場景務必加入**批次提交/事務控制/進度日誌**,並配合 SSIS/BCP 等重型工具評估選型。