找到一種不錯的從SQLServer轉成Mysql資料庫的方法

來源:互聯網
上載者:User

年初的時候一直在做一個網站MSSQL2000 -> MySQL5的遷移工作,因為採用了不同的程式系統,所以主要問題在資料的遷移。由於2個系統資料庫結構差異非常大,不方便採取SQL SERVER裡匯入MYSQL的ODBC資料來源的功能(也不推薦這麼做,欄位類型等不同點會搞死人的~),因此就在WINDOWS下自己寫PHP指令碼從SQLSERVER裡讀資料,然後按照新系統的需要處理之後插入MYSQL裡面,靈活也比較方便。實際過程主要有下面幾個問題:

1、資料庫的串連,主要是串連SQL SERVER。主要有3種方法:
1.1 利用PHP中的mssql_系列函數,這個與使用mysql_系列函數類似,不過要開啟php.ini中相關擴充(extension=php_mssql.dll)。
1.2 利用ODBC串連,由於抽象了具體資料庫,所以沒有辦法利用資料表欄位名=>數組鍵名的特性,在針對具體應用時不是很方便,代碼形式:

$conn = odbc_connect("datasource","username","password");
$sql = "select * from news";
$cur= odbc_exec($conn, $sql);
while(odbc_fetch_row($cur)){
$field1 = odbc_result($cur,1);
$field2 = odbc_result($cur,2);
//do something
}
1.3 使用PDO - PHP5中加入資料對象抽象層,作為官方推出的資料提供者,優點有很多,比如支援參數綁定以防止SQL注入;對於不同資料庫載入不同驅動即可,程式碼是一致的,便於移植等等,相信應該是大勢所趨。不過由於用了PHP5全新的物件導向特性,需要PHP5的支援,5.1可以直接使用,5需要裝PECL,另外還要修改PHP.ini,增加:extension=php_pdo_mysql.dll和extension=php_pdo_mssql.dll,實際代碼如下:

try {
$DBH=new PDO("mssql:dbname=XXX;host=localhost",
"root", "password");//Connect to DB
} catch (PDOException $e) {
print "Error!: " . $e->getMessage();//Error Message
die();
}
$stmt = $DBH->prepare("SELECT * FROM news");//Stmt Handle $stmt
if ($stmt->execute()) {
while ($row = $stmt->fetch()) {
//do something
}
}
$stmt2 = $mssql->prepare("INSERT INTO news
(title,author) VALUES (:title, :author)");
$stmt2->bindParam(':title', $title);
$stmt2->bindParam(':author', $author);
$stmt2->execute();
$DBH = null;// Close Connection這裡要提醒下的是MSSQL裡面是沒有MYSQL中LIMIT這個文法的。

2、TEXT欄位被截斷的問題。
上面嘗試了3種串連資料庫方法,是因為當初連上MSSQL後SELECT出來的資料總是只有4K長度,以為是串連方式限制導致的,所以換了幾種都是這樣,最後查了資料才知道,是php.ini裡面這2句配置的問題:
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 4096

; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 4096
把4096改成-1(代表無限制)即可,也可以使用mssql_query("SET TEXTSIZE 65536");來實現。

3.兩種資料庫欄位類型不同的問題有2個地方需要講一下,一個是欄位支援最大長度要注意,以免插入資料庫時候被截斷,另外一個就是日期格式的問題了,我比較喜歡用UNIX時間戳記。在連MSSQL時候可以用 "select unix_timestamp(created) from news" 來實現MSSQL裡面DATETIME到MYSQL裡時間戳記的轉換。不過遷移時候一次要提取表中所有欄位,像上面這種方法就沒有簡單的"select * from news"簡潔,需要羅列所有欄位。實際可以直接SELECT出來,得到的是一個字串,比如在MSSQL裡面是2006-01-01 12:01,取出來的字串是"2006 一月 01 12:01"(有些奇怪,不知道為什麼會產生中文)。用下面這個函數可以轉換成時間戳記:

function ConvertTime($timestring){
if($timestring == null){
return 0;
}
$time = explode(" ",$timestring);
$year = $time[0];
switch ($time[1]){
case "一月":$month = "1";break;
case "二月":$month = "2";break;
case "三月":$month = "3";break;
case "四月":$month = "4";break;
case "五月":$month = "5";break;
case "六月":$month = "6";break;
case "七月":$month = "7";break;
case "八月":$month = "8";break;
case "九月":$month = "9";break;
case "十月":$month = "10";break;
case "十一月":$month = "11";break;
case "十二月":$month = "12";break;
default:break;
}
$day = $time[2];
$h = 0;
$m = 0;
$s = 0;
if(!empty($time[3])){
$time2 = explode(":",$time[3]);
$h = $time2[0];
$i = $time2[1];
}
//return date("Y-m-d H:i:s",mktime($h,$i,$s,$month,$day,$year));
return mktime($h,$i,$s,$month,$day,$year);
}最後轉換指令碼寫完了可以在CMD視窗裡面用php.exe abc.php來執行,這種方式是沒有逾時時間的,適合遷移大批量資料。
基本上就是這些內容,希望對大家有協助。

Update(06/05/05):關於時間戳記的轉換,在php.ini中加上
mssql.datetimeconvert = Off
後就能得到類似2006-01-01 12:01不帶有中文的格式了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.