2011年1月11日 星期二

Oracle migrate to MySQL

一、從Oracle移植到MySQL主要有六個方面的內容需要移植,一是表Table,包括表結構和數據,二是觸發器Trigger,三是存儲過程Procedure,函數function和包Package,四是任務Job ,五是用戶等其他方面的移植,六是具體應用程序通過SQL語句訪問時的細節差異克服。筆者用來移植測試的數據庫是:Oracle 9i ,MySQL 6.0,Windows 2000環境。

二、經過映射轉換,比如number會轉換為double,date轉換為timestamp等,請小心處理日期字段的默認值等,表的主鍵,表的索引(Oracle的位圖索引會被轉成BTree索引,另外表和字段的註釋會丟失)等信息。需要特別注意的是,Oracle的自增字段的處理。提供字段自增屬性。
三、觸發器的移植首先,MySQL在6.0以後才支持觸發器!觸發器的移植沒有現成工具,因為兩者之間的語法差異較大,您只能通過手工對照著原來的邏輯一個一個添加。
四、存儲過程,函數和程序包的移植程序包是Oracle用來組織邏輯功能的一個Object,MySQL不支持,因此需要將包裡的存儲過程﹑函數等全部放到該數據庫公有過程和函數里面。

五、Job的移植Job是Oracle的定時任務實現的方法,MySQL6中用Event實現,具體語法請參考MySQL手冊。

六、用戶的移植Oracle的用戶管理和MySQL下有較大區別,請分別建立用戶,並賦予合適的權限。

七、應用程序的移植由於語法細節上的差異,導致很多SQL語句需要改寫。筆者記下了所有移植過程中碰到的SQL語句細節差異,列出來以供參考:
1)Oracle的to_char函數不能再使用,換用如CONCAT(14.3)的形式,為了提高應用程序兼容性,建議手工寫一個
2)Oracle的to_date函數不能再使用,建議手工寫一個添加到MySQL數據庫
eg:
to_char(sysdate,'yyyy-mm-dd')-->date_format(sysdate(),'%Y-%m-%d');
to_date(sysdate,'yyyy-mm-dd')-->STR_TO_DATE(sysdate(),'%Y-%m-%d');
to_char(add_months(to_date ('20000101','yyyymmdd'),1),'yyyy-mm-dd')-->date_add('2000-01-01',interval 1 month);

3)Oracle的decode函數不能再使用,換用SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END 的形式
4)nvl這樣的一些專用函數,MySQL是沒有的,可以把select nvl(to_char(num),'nothing') from t_equipment轉換成select case num when num then num else 'nothing' end from t_equipment
5)instr之類的函數,函數名相同,但參數個數不同
6)Oracle的sysdate要寫成sysdate()的形式
7)包的形式已經取消,所以原來以包的方式調用的過程如xx_pack.xxx要寫成xxx()
8)帶進製字符轉數字Oracle風格:TO_NUMBER(strTmp,'XX') TO_NUMBER('9')MySQL風格:CONV(strTmp,16,10) CONV('9',10,10) 如果字符串前後有加減操作,會隱含轉換成數字
9) 不能再有直接調用序列的形式,如果一定需要,可以模擬實現一個
10)日期直接加減的含義不同了,比如Oracle中sysdate + 1 變成了sysdate() + interval 1 day(注意如果寫成sysdate() + 1 語法還是正確的,但含義是錯誤的)查詢select sysdate() + 1 from dual 在MySQL得到比如20080223153234(= 20080223153233 + 1)的數而在Oracle中會得到第二天當前時刻。
11) MySQL單純的date類型只是日期不帶時間,DATETIME或TIMESTAMP帶有時間,用DATE_FORMAT函數可以控制顯示形式
12)select 'abc' || 'd' from dual 兩個數據執行的結果不同(語法都能通過),MySQL要寫成select concat('abc' , 'd')的形式
13) Oracle高級功能,如帶有暗示索引的select語句,MySQL是不支持的(語法可以通過)
14)有些MySQL的保留字不能直接用在SQL語句裡,要加表名或別名限制,如select RIGHT FROM XX要改成select a.RIGHT FROM XX a
15) Oracle的子查詢可以不起別名,但MySQL是必須的,比如下面的別名aa:select field1 from (select sysdate() as field1 from dual) as aa
16)很多系統表名都是不同的,比如,列出某個表的信息:select * from tab where TName='T_TEST'改成select table_name,table_type from information_schema.tables where table_schema = 'user' and table_name= ' T_TEST '
17)MySQL下update時不能有本身的子查詢update T_TEST set Flag = 0 where field1 in
(select distinct b.field1 from T_TEST b where b.flag=1)
18)Oracle下''和null等價,而MySQL則不然select 1 from dual where '' is null在Oracle下可以取到記錄,在MySQL下不能dual表的使用,substr、trim等函數的主要使用方式和Oracle類似

八、小結和建議看起來,Oracle移植到MySQL似乎挺麻煩,有沒有一鍵完成的簡單辦法?呵呵,我沒有找到,除非您只使用基本表,只使用基本SQL語句訪問它。

source: http://shshy39.javaeye.com/blog/342512

1 則留言:

taricyao 提到...

How to get to The Star Grand at The Star Gold Coast by Bus - Mapyro
Directions to The Star Grand at The 구리 출장안마 Star Gold 제천 출장마사지 Coast (Broadbeach) with public 경상남도 출장마사지 transportation. The following transit lines 대전광역 출장안마 have routes that pass near The 안성 출장안마 Star