一、從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
(澳門)炒家、用家 樓市拉鋸戰
13 年前