首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL Server 遷移 MySQL 實戰:PHP 腳本異構資料搬移、型別對應與大字段處理

     編輯:MySQL 資料庫相關知識

專案背景

MSSQL 2000 → MySQL 5.x,系統重構導致資料庫結構差異大,不適合直接 ODBC 連結匯入,採用 PHP 腳本「讀 MSSQL → 轉換 → 寫 MySQL」彈性遷移。

三種 PHP 連接 MSSQL 方式比較

方式優點缺點適用場景
mssql_* 函數語法類似 mysql_*,簡單PHP 5.3+ 已移除、僅支援舊版 FreeTDS舊專案維護
ODBC (odbc_*)跨資料庫抽象無法以欄位名索引陣列、程式碼冗長多資料庫支援
PDO (PHP 5.1+)參數綁定防注入、統一介面、支援預處理、可移植需 PHP 5.1+、啟用 pdo_mssql/pdo_dblib推薦:新專案首選

PDO 遷移核心程式碼骨架

try {
    $mssql = new PDO("dblib:host=localhost;dbname=src_db", "user", "pass");
    $mysql = new PDO("mysql:host=localhost;dbname=dst_db", "user", "pass");
    $mysql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) { die("Connect failed: " . $e->getMessage()); }

// 讀取 MSSQL
$stmt = $mssql->query("SELECT id, title, content, created FROM news");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // 轉換邏輯
    $title = $row['title'];
    $content = $row['content'];
    $created = convertMssqlDateTime($row['created']); // 自訂函數

    // 寫入 MySQL(參數綁定)
    $ins = $mysql->prepare("INSERT INTO news(title, content, created) VALUES(?, ?, ?)");
    $ins->execute([$title, $content, $created]);
}

關鍵問題與解決

1. TEXT/NTEXT 欄位被截斷(預設 4096 位元組)

修改 php.ini:

mssql.textlimit = -1
mssql.textsize = -1

或執行 SQL:SET TEXTSIZE 2147483647;(PDO 執行即可)。

2. 日期時間格式轉換

MSSQL DATETIME 讀出為字串(如 Jan 1 2006 12:01PM),需解析為 Unix Timestamp:

function convertMssqlDateTime($str) {
    if (!$str) return 0;
    // 移除中文月份(若 php.ini 設定 mssql.datetimeconvert = Off 可避免)
    $str = str_replace(
        ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'],
        ['01','02','03','04','05','06','07','08','09','10','11','12'],
        $str
    );
    return strtotime($str); // 或 DateTime::createFromFormat
}

最佳做法:在 php.ini 設定 mssql.datetimeconvert = Off,MSSQL 直接回傳 YYYY-MM-DD HH:MM:SS 格式,免解析。

3. 型別對應表(常見)

MSSQLMySQL 建議備註
int / bigintINT / BIGINT
decimal(p,s)DECIMAL(p,s)
varchar(n) / nvarchar(n)VARCHAR(n) / VARCHAR(n*3) utf8mb4nvarchar 需預留 3 倍長度
text / ntextTEXT / MEDIUMTEXT / LONGTEXT配合 textsize
datetime / smalldatetimeDATETIME / TIMESTAMPTimestamp 範圍 1970-2038
bitTINYINT(1)
uniqueidentifierCHAR(36) / BINARY(16)存 UUID 字串或二進位

大量資料執行建議

  • CLI 模式執行:php migrate.php(無 HTTP 超時限制)。
  • 分批 Commit:每 500-1000 筆 $mysql->commit(),避免長交易鎖表。
  • 記錄進度:寫入遷移日誌表或檔案,支援斷點續傳。
  • 關閉索引/外鍵再開啟:
    SET FOREIGN_KEY_CHECKS=0; ALTER TABLE t DISABLE KEYS; → 匯入 → ENABLE KEYS; FOREIGN_KEY_CHECKS=1;

驗證與上線

  1. 行數比對:SELECT COUNT(*) FROM news 雙邊一致。
  2. 2. 抽樣比對關鍵欄位(MD5/CRC32)。 3. 應用層功能測試、效能基準測試。 4. 切換 DNS/連線字串,保留回滾方案。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved