找到一種不錯(cuò)的從SQLServer轉(zhuǎn)成Mysql數(shù)據(jù)庫(kù)的方法
更新時(shí)間:2007年07月29日 17:59:35 作者:
年初的時(shí)候一直在做一個(gè)網(wǎng)站MSSQL2000 -> MySQL5的遷移工作,因?yàn)椴捎昧瞬煌某绦蛳到y(tǒng),所以主要問(wèn)題在數(shù)據(jù)的遷移。由于2個(gè)系統(tǒng)數(shù)據(jù)庫(kù)結(jié)構(gòu)差異非常大,不方便采取SQL SERVER里導(dǎo)入MYSQL的ODBC數(shù)據(jù)源的功能(也不推薦這么做,字段類型等不同點(diǎn)會(huì)搞死人的~),因此就在WINDOWS下自己寫PHP腳本從SQLSERVER里讀數(shù)據(jù),然后按照新系統(tǒng)的需要處理之后插入MYSQL里面,靈活也比較方便。實(shí)際過(guò)程主要有下面幾個(gè)問(wèn)題:
1、數(shù)據(jù)庫(kù)的連接,主要是連接SQL SERVER。主要有3種方法:
1.1 利用PHP中的mssql_系列函數(shù),這個(gè)與使用mysql_系列函數(shù)類似,不過(guò)要打開php.ini中相關(guān)擴(kuò)展(extension=php_mssql.dll)。
1.2 利用ODBC連接,由于抽象了具體數(shù)據(jù)庫(kù),所以沒有辦法利用數(shù)據(jù)表字段名=>數(shù)組鍵名的特性,在針對(duì)具體應(yīng)用時(shí)不是很方便,代碼形式:
$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中加入數(shù)據(jù)對(duì)象抽象層,作為官方推出的數(shù)據(jù)訪問(wèn)接口,優(yōu)點(diǎn)有很多,比如支持參數(shù)綁定以防止SQL注入;對(duì)于不同數(shù)據(jù)庫(kù)加載不同驅(qū)動(dòng)即可,程序代碼是一致的,便于移植等等,相信應(yīng)該是大勢(shì)所趨。不過(guò)由于用了PHP5全新的面向?qū)ο筇匦裕枰狿HP5的支持,5.1可以直接使用,5需要裝PECL,另外還要修改PHP.ini,增加:extension=php_pdo_mysql.dll和extension=php_pdo_mssql.dll,實(shí)際代碼如下:
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這個(gè)語(yǔ)法的。
2、TEXT字段被截?cái)嗟膯?wèn)題。
上面嘗試了3種連接數(shù)據(jù)庫(kù)方法,是因?yàn)楫?dāng)初連上MSSQL后SELECT出來(lái)的數(shù)據(jù)總是只有4K長(zhǎng)度,以為是連接方式限制導(dǎo)致的,所以換了幾種都是這樣,最后查了資料才知道,是php.ini里面這2句配置的問(wèn)題:
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 4096
; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 4096
把4096改成-1(代表無(wú)限制)即可,也可以使用mssql_query("SET TEXTSIZE 65536");來(lái)實(shí)現(xiàn)。
3.兩種數(shù)據(jù)庫(kù)字段類型不同的問(wèn)題有2個(gè)地方需要講一下,一個(gè)是字段支持最大長(zhǎng)度要注意,以免插入數(shù)據(jù)庫(kù)時(shí)候被截?cái)?,另外一個(gè)就是日期格式的問(wèn)題了,我比較喜歡用UNIX時(shí)間戳。在連MSSQL時(shí)候可以用 "select unix_timestamp(created) from news" 來(lái)實(shí)現(xiàn)MSSQL里面DATETIME到MYSQL里時(shí)間戳的轉(zhuǎn)換。不過(guò)遷移時(shí)候一次要提取表中所有字段,像上面這種方法就沒有簡(jiǎn)單的"select * from news"簡(jiǎn)潔,需要羅列所有字段。實(shí)際可以直接SELECT出來(lái),得到的是一個(gè)字符串,比如在MSSQL里面是2006-01-01 12:01,取出來(lái)的字符串是"2006 一月 01 12:01"(有些奇怪,不知道為什么會(huì)產(chǎn)生中文)。用下面這個(gè)函數(shù)可以轉(zhuǎn)換成時(shí)間戳:
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);
}最后轉(zhuǎn)換腳本寫完了可以在CMD窗口里面用php.exe abc.php來(lái)執(zhí)行,這種方式是沒有超時(shí)時(shí)間的,適合遷移大批量數(shù)據(jù)。
基本上就是這些內(nèi)容,希望對(duì)大家有幫助。
Update(06/05/05):關(guān)于時(shí)間戳的轉(zhuǎn)換,在php.ini中加上
mssql.datetimeconvert = Off
后就能得到類似2006-01-01 12:01不帶有中文的格式了。
1、數(shù)據(jù)庫(kù)的連接,主要是連接SQL SERVER。主要有3種方法:
1.1 利用PHP中的mssql_系列函數(shù),這個(gè)與使用mysql_系列函數(shù)類似,不過(guò)要打開php.ini中相關(guān)擴(kuò)展(extension=php_mssql.dll)。
1.2 利用ODBC連接,由于抽象了具體數(shù)據(jù)庫(kù),所以沒有辦法利用數(shù)據(jù)表字段名=>數(shù)組鍵名的特性,在針對(duì)具體應(yīng)用時(shí)不是很方便,代碼形式:
$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中加入數(shù)據(jù)對(duì)象抽象層,作為官方推出的數(shù)據(jù)訪問(wèn)接口,優(yōu)點(diǎn)有很多,比如支持參數(shù)綁定以防止SQL注入;對(duì)于不同數(shù)據(jù)庫(kù)加載不同驅(qū)動(dòng)即可,程序代碼是一致的,便于移植等等,相信應(yīng)該是大勢(shì)所趨。不過(guò)由于用了PHP5全新的面向?qū)ο筇匦裕枰狿HP5的支持,5.1可以直接使用,5需要裝PECL,另外還要修改PHP.ini,增加:extension=php_pdo_mysql.dll和extension=php_pdo_mssql.dll,實(shí)際代碼如下:
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這個(gè)語(yǔ)法的。
2、TEXT字段被截?cái)嗟膯?wèn)題。
上面嘗試了3種連接數(shù)據(jù)庫(kù)方法,是因?yàn)楫?dāng)初連上MSSQL后SELECT出來(lái)的數(shù)據(jù)總是只有4K長(zhǎng)度,以為是連接方式限制導(dǎo)致的,所以換了幾種都是這樣,最后查了資料才知道,是php.ini里面這2句配置的問(wèn)題:
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 4096
; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 4096
把4096改成-1(代表無(wú)限制)即可,也可以使用mssql_query("SET TEXTSIZE 65536");來(lái)實(shí)現(xiàn)。
3.兩種數(shù)據(jù)庫(kù)字段類型不同的問(wèn)題有2個(gè)地方需要講一下,一個(gè)是字段支持最大長(zhǎng)度要注意,以免插入數(shù)據(jù)庫(kù)時(shí)候被截?cái)?,另外一個(gè)就是日期格式的問(wèn)題了,我比較喜歡用UNIX時(shí)間戳。在連MSSQL時(shí)候可以用 "select unix_timestamp(created) from news" 來(lái)實(shí)現(xiàn)MSSQL里面DATETIME到MYSQL里時(shí)間戳的轉(zhuǎn)換。不過(guò)遷移時(shí)候一次要提取表中所有字段,像上面這種方法就沒有簡(jiǎn)單的"select * from news"簡(jiǎn)潔,需要羅列所有字段。實(shí)際可以直接SELECT出來(lái),得到的是一個(gè)字符串,比如在MSSQL里面是2006-01-01 12:01,取出來(lái)的字符串是"2006 一月 01 12:01"(有些奇怪,不知道為什么會(huì)產(chǎn)生中文)。用下面這個(gè)函數(shù)可以轉(zhuǎn)換成時(shí)間戳:
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);
}最后轉(zhuǎn)換腳本寫完了可以在CMD窗口里面用php.exe abc.php來(lái)執(zhí)行,這種方式是沒有超時(shí)時(shí)間的,適合遷移大批量數(shù)據(jù)。
基本上就是這些內(nèi)容,希望對(duì)大家有幫助。
Update(06/05/05):關(guān)于時(shí)間戳的轉(zhuǎn)換,在php.ini中加上
mssql.datetimeconvert = Off
后就能得到類似2006-01-01 12:01不帶有中文的格式了。
您可能感興趣的文章:
- 使用Navicat Premium將SQLServer數(shù)據(jù)導(dǎo)出為sql格式
- navicat無(wú)法遠(yuǎn)程連接mysql的解決方法
- Navicat異地自動(dòng)備份MySQL方法詳解(圖文)
- Mysql安裝 Navicat 出現(xiàn)1044/1045錯(cuò)誤的解決方法
- Navicat for MySQL 亂碼問(wèn)題解決方法
- 簡(jiǎn)單實(shí)現(xiàn)SQLServer轉(zhuǎn)MYSQL的方法
- MySQL數(shù)據(jù)庫(kù)轉(zhuǎn)移,access,sql server 轉(zhuǎn) MySQL 的圖文教程
- 使用mss2sql工具將SqlServer轉(zhuǎn)換為Mysql全記錄
- Navicat遠(yuǎn)程連接SQL Server并轉(zhuǎn)換成MySQL步驟詳解
相關(guān)文章
MySQL事務(wù)實(shí)現(xiàn)可重復(fù)讀
MySQL數(shù)據(jù)庫(kù)的默認(rèn)事務(wù)隔離級(jí)別是可重復(fù)讀,本文主要介紹了MySQL事務(wù)實(shí)現(xiàn)可重復(fù)讀,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12
一文帶你學(xué)會(huì)MySQL的select語(yǔ)句
在MySQL中可以使用SELECT語(yǔ)句來(lái)查詢數(shù)據(jù),查詢數(shù)據(jù)是指從數(shù)據(jù)庫(kù)中根據(jù)需求,使用不同的查詢方式來(lái)獲取不同的數(shù)據(jù),是使用頻率最高、最重要的操作,下面這篇文章主要給大家介紹了關(guān)于MySQL中select語(yǔ)句的相關(guān)資料,需要的朋友可以參考下2022-11-11
淺談Mysql大數(shù)據(jù)分頁(yè)查詢解決方案
本文主要介紹了淺談Mysql大數(shù)據(jù)分頁(yè)查詢解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
MySQL提示The InnoDB feature is disabled需要開啟InnoDB的解決方法
這篇文章主要介紹了MySQL提示The InnoDB feature is disabled需要開啟InnoDB的解決方法,簡(jiǎn)單分析了MySQL數(shù)據(jù)庫(kù)開啟InnoDB引擎的實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-01-01
MySQL中的引號(hào)和反引號(hào)的區(qū)別與用法詳解
這個(gè)問(wèn)題是我在學(xué)習(xí)數(shù)據(jù)庫(kù)的時(shí)候遇到的一個(gè)問(wèn)題,我當(dāng)時(shí)并不能理解下圖中的一些情況,后來(lái)我也請(qǐng)教了一位大佬給我解答,最后在大佬和度娘的幫助下我大概理解了這個(gè)反引號(hào)的東西2021-10-10
介紹一個(gè)針對(duì)C++程序的MySQL訪問(wèn)庫(kù)soci
這篇文章主要介紹了介紹一個(gè)針對(duì)C++程序的MySQL訪問(wèn)庫(kù)soci,文章中還講了其中的一些操作方法,需要的朋友可以參考下2015-05-05

