首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 將 Access (MDB) 資料遷移至 MySQL 完整實作:COM 元件、編碼轉換、分批處理

     編輯:PHP 綜合知識

早期 ASP 系統常使用 Access (`.mdb`) 做資料儲存,遷移至 PHP + MySQL 時需將資料導出。本文提供在 Windows 環境下,利用 PHP COM 元件操作 ADODB 連接 Access、逐筆讀取、編碼轉換 (GBK/Big5 → UTF-8)、批次寫入 MySQL 的完整方案。

前置需求

  • Windows 作業系統 (COM 元件僅支援 Windows)
  • PHP 啟用 php_com_dotnet.dll 擴充 (`extension=com_dotnet`)
  • 安裝 Microsoft Access Database Engine (32/64 位元需與 PHP 執行環境一致)
    Access Database Engine 2016 Redistributable
  • MySQL 已建立對應資料表結構

完整遷移腳本

<?php
set_time_limit(0);
ini_set('memory_limit', '512M');

// ==================== 1. 連接 MySQL ====================
$myHost = 'localhost:3306';
$myUser = 'root';
$myPass = 'password';
$myDb   = 'target_db';
$myPrefix = 'sdb_'; // 表前綴

$myLink = mysqli_connect($myHost, $myUser, $myPass, $myDb);
if (!$myLink) die('MySQL 連線失敗:' . mysqli_connect_error());
mysqli_set_charset($myLink, 'utf8mb4');

// ==================== 2. 連接 Access (COM ADODB) ====================
$mdbPath = realpath('data.mdb'); // 絕對路徑
if (!$mdbPath || !file_exists($mdbPath)) die('MDB 檔案不存在:' . $mdbPath);

$conn = new COM('ADODB.Connection') or die('無法建立 ADODB.Connection');
$connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$mdbPath;";
// 舊版 .mdb 可用:Provider=Microsoft.Jet.OLEDB.4.0;

try {
    $conn->Open($connStr);
} catch (com_exception $e) {
    die('Access 開啟失敗:' . $e->getMessage() . ' (請確認已安裝 Access Database Engine)');
}

$rs = new COM('ADODB.Recordset');
// 查詢需遷移的資料,可加 WHERE 條件篩選
$sql = "SELECT * FROM `information` WHERE `lanmu3id` = 13";
$rs->Open($sql, $conn, 1, 1); // adOpenKeyset, adLockReadOnly

// ==================== 3. 逐筆遷移 ====================
$batchSize = 500; // 批次大小
$batch = [];
$count = 0;

while (!$rs->EOF) {
    // 取欄位值並轉碼 (Access 常為 GB2312/Big5)
    $id       = iconv('GB2312', 'UTF-8//IGNORE', $rs->Fields('ID')->value);
    $title    = iconv('GB2312', 'UTF-8//IGNORE', $rs->Fields('title')->value);
    $summary  = iconv('GB2312', 'UTF-8//IGNORE', $rs->Fields(1)->value); // 索引也可
    $content  = iconv('GB2312', 'UTF-8//IGNORE', $rs->Fields('content')->value);
    $download = iconv('GB2312', 'UTF-8//IGNORE', $rs->Fields('download')->value);

    // 組裝 INSERT (使用預處理防注入、效能更好)
    $batch[] = "('$id', '$category_id', '$title', '$content', UNIX_TIMESTAMP(), 1, NULL, NULL, NULL, NULL, 'false')";

    $rs->MoveNext();
    $count++;

    // 達批次大小執行
    if (count($batch) >= $batchSize) {
        $sql = "INSERT INTO `{$myPrefix}articles` 
                (`article_id`,`node_id`,`title`,`content`,`uptime`,`ifpub`,`align`,`filetype`,`filename`,`orderlist`,`disabled`) 
                VALUES " . implode(',', $batch);
        if (!mysqli_query($myLink, $sql)) {
            error_log('批次寫入失敗:' . mysqli_error($myLink) . "\nSQL: $sql");
        }
        $batch = [];
        echo "已處理 $count 筆...
"; flush(); // 即時輸出進度 } } // 餘數寫入 if ($batch) { $sql = "INSERT INTO `{$myPrefix}articles` ... VALUES " . implode(',', $batch); mysqli_query($myLink, $sql); } echo "
遷移完成,共 $count 筆。"; // 關閉連線 $rs->Close(); $conn->Close(); mysqli_close($myLink); ?>

關鍵技術點解析

1. Provider 選擇

  • Microsoft.ACE.OLEDB.12.0:支援 `.accdb` (Access 2007+) 與 `.mdb`,需安裝 2010/2016 Redistributable。
  • Microsoft.Jet.OLEDB.4.0:僅支援 `.mdb` (Access 2003 及之前),32 位元限制。

建議統一用 ACE 12.0,相容性最好。

2. 編碼轉換

Access 內部儲存通常為 GB2312 (簡體) 或 Big5 (繁體)。使用 iconv('GB2312', 'UTF-8//IGNORE', $val):

  • //IGNORE:跳過無法轉換的字元,避免中斷。
  • //TRANSLIT:嘗試近似替換 (如全形→半形)。

3. COM 例外處理

COM 操作會拋出 com_exception,必須 try-catch 捕獲,否則腳本直接終止且無錯誤日誌。

4. 批次寫入優化

  • 單筆 INSERT 效能極差 (每次網路往返、事務提交)。
  • 批次 INSERT ... VALUES (),(),() 可提升 10-50 倍速度。
  • 批次大小 500-2000 筆平衡記憶體與效能。
  • 正式環境建議改用 mysqli_prepare + bind_param 迴圈執行,更安全、可重用执行计划。

5. 大數據量分批遷移策略

// Access SQL 支援 TOP 與 WHERE 條件分頁
$pageSize = 10000;
$offset = 0;
while (true) {
    $sql = "SELECT * FROM `information` WHERE `lanmu3id` = 13 ORDER BY `ID` LIMIT $offset, $pageSize";
    // Access 不支援 LIMIT,改用:
    // SELECT TOP $pageSize * FROM ... WHERE ID > $lastId ORDER BY ID
    // 需記住上一批最後一筆 ID
    // ...
    if ($rs->EOF) break;
    // 處理當前批次
    $offset += $pageSize;
}

替代方案:匯出 CSV 再導入

若環境不支援 COM (如 Linux 伺服器),可在 Windows 本機:

  1. Access 開啟 `.mdb` → 「外部資料」→ 「匯出」→ 「文字檔」→ 選 CSV、UTF-8 編碼。
  2. 將 CSV 上傳至伺服器。
  3. 用 LOAD DATA INFILE 或 `fgetcsv` 批次導入 MySQL,速度最快、最穩定。

驗證清單

  • ☐ 筆數比對:`SELECT COUNT(*) FROM access_table` vs `SELECT COUNT(*) FROM mysql_table`
  • ☐ 關鍵欄位抽樣:ID、標題、時間、長文本完整性
  • ☐ 特殊字元:Emoji、全形符號、換行符是否正確保存
  • ☐ 索引/主鍵/外鍵關係是否重建

小結

PHP + COM + ADODB 是 Windows 環境下遷移 Access 資料最直接的方式。關鍵在於:正確安裝 ACE Provider、處理 GB2312→UTF-8 編碼、批次寫入優化效能、COM 例外捕獲。大專案建議改用「匯出 CSV → LOAD DATA INFILE」離線遷移,更穩定、可重試、不佔用 Web 執行緒。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved