一種不錯的從SQL轉Mysql數據庫的方法

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

1、數據庫的連接,主要是連接SQLSERVER。主要有3種方法:

1.1利用PHP中的mssql_系列函數,這個與使用mysql_系列函數類似,不過要打開php.ini中相關擴展(extension=php_mssql.dll)。

1.2利用ODBC連接,由於抽象了具體數據庫,所以沒有辦法利用數據表字段名=>數組鍵名的特性,在針對具體應用時不是很方便,代碼形式:

 

$conn=odbc_connect("datasource","username","password");

$sql="select*fromnews";

$cur=odbc_exec($conn,$sql);

while(odbc_fetch_row($cur)){

$field1=odbc_result($cur,1);

$field2=odbc_result($cur,2);

//dosomething

}

1.3使用PDO-PHP5中加入數據對象抽象層,作爲官方推出的數據訪問接口,優點有很多,比如支持參數綁定以防止SQL注入;對於不同數據庫加載不同驅動即可,程序代碼是一致的,便於移植等等,相信應該是大勢所趨。不過由於用了PHP5全新的面向對象特性,需要PHP5的支持,5.1可以直接使用,5需要裝PECL,另外還要修改PHP.ini,增加:extension=php_pdo_mysql.dllextension=php_pdo_mssql.dll,實際代碼如下:

 

try{

$DBH=newPDO("mssql:dbname=XXX;host=localhost", 

"root","password");//ConnecttoDB

}catch(PDOException$e){

print"Error!:".$e->getMessage();//ErrorMessage

die();

}

$stmt=$DBH->prepare("SELECT*FROMnews");//StmtHandle$stmt

if($stmt->execute()){

while($row=$stmt->fetch()){

//dosomething

}

}

$stmt2=$mssql->prepare("INSERTINTOnews 

(title,author)VALUES(:title,:author)");

$stmt2->bindParam(':title',$title);

$stmt2->bindParam(':author',$author);

$stmt2->execute();

$DBH=null;//CloseConnection這裏要提醒下的是MSSQL裏面是沒有MYSQLLIMIT這個語法的。

 

2TEXT字段被截斷的問題。

上面嘗試了3種連接數據庫方法,是因爲當初連上MSSQLSELECT出來的數據總是隻有4K長度,以爲是連接方式限制導致的,所以換了幾種都是這樣,最後查了資料才知道,是php.ini裏面這2句配置的問題:

 

;Validrange0-2147483647.Default=4096.

mssql.textlimit=4096

;Validrange0-2147483647.Default=4096.

mssql.textsize=4096

4096改成-1(代表無限制)即可,也可以使用mssql_query("SETTEXTSIZE65536");來實現。

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

 

            functionConvertTime($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];

}

//returndate("Y-m-dH:i:s",mktime($h,$i,$s,$month,$day,$year));

returnmktime($h,$i,$s,$month,$day,$year);

}

            

 

最後轉換腳本寫完了可以在CMD窗口裏面用php.exeabc.php來執行,這種方式是沒有超時時間的,適合遷移大批量數據。

基本上就是這些內容,希望對大家有幫助。 

Update(06/05/05):關於時間戳的轉換,在php.ini中加上

mssql.datetimeconvert=Off

後就能得到類似2006-01-0112:01不帶有中文的格式了。

發佈了13 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章