最近有一個項目要把原來使用的Sybase資料庫改為Oracle資料庫, 所以我要把sybase的指令碼改成oracle的指令碼, 如表結構, 預存程序, 視圖等的指令碼. 這種改指令碼的情況可能很久才能遇到一次吧, 放到blog裡面, 以後需要自己再看看, 溫故知新.
(所用sybase版本是11.9.2, oracle是10g)
1. if exists
用Regex where id = object_id/(/'[A-Z_]+/'/)
判斷表是否存在這段不要了, 直接drop table
2. go (注意要用全詞匹配)
替換為 /
3. varchar (這個要提前換)
替換為 varchar2
4. text
替換為 varchar2(4000), 還不夠的話可以用 clob代替
5. datetime
替換為 date, 或者 TIMESTAMP, 後者精確到毫秒
6. 建立表的指令碼中不要存在空行, 不然在用命令視窗匯入的時候會出現錯誤
在editplus中用 Regex ^[ /t]*/n 替換為 空格 取消空行( ^ 為行頭開始, /n 為分行符號)
全部替換的按鈕按多幾次, 再檢查下
7. dbo.
替換為空白格或者使用者名稱
8. 建立主鍵
CONSTRAINT PK_BDG_SDC_PRJ_ZP PRIMARY KEY CLUSTERED (ID)
中的CLUSTERED 要去掉
9. 去掉 LOCK ALLPAGES
10. getdate()
替換為 sysdate
11. isnull()
替換為 nvl()
11. 如果出現重複建立表的時候
把表上面的注釋 /*********/ /****************
/* */ 改為 * *
/*********/ *****************/
原先不是很清楚, 不過通常是下面要建立的表的名稱太長就會出現這種情況
12. 預存程序
A. 參數: 在預存程序名稱後面(p1, p2,.....)
命名開頭不能為 @ ;
要指明in 和 out ;
參數類型不能帶括弧部分;
B. 變數: 不用關鍵字 declare , 直接" t_time varchar2(20); t_seq int; "(注意要帶" ; ") ;
在as 和 begin 中間定義;
給變數賦值 " varA := value; "
和" select keyA into varA from tableA; " ;
C. 在每個完整的語句後面要加 " ; ";
沒有直接" return 1 ; "的, 但是可以" return; " 直接中斷預存程序;
沒有" begin transaction ", 但可以用" commit; "和" rollback; " (是不是每次執行都會建立隱性的事務我就不知道了);
要返回select的結果集, 必須用遊標, 不過需要建立一個包A才行, 在這個包A中定義一個"type cursorType is ref cursor; "這樣一個遊標
類型, 然後再加一個輸出參數"p_cursor out A.cursorType ", 內容裡面" open p_cursor for select ......; " ;
DDL的語句必須用動態SQL, 如"v_sql:='drop table TMP_XMZ_REPORT'; EXECUTE IMMEDIATE v_sql; ";
D. 控制結構
if...else
sybase: if(條件) begin 代碼塊 end(如果只有一句代碼, 可以不用begin end)
else begin 代碼塊 end(如果只有一句代碼, 可以不用begin end)
oracle: if(條件) then 代碼塊
else 代碼塊 end if;
E. 遊標
在sybase裡面可以直接 " declare CUR1 cursor for select..... ", 這個貌似在oracle不行,
不過可以用" for cur1_record in ( select....) loop 代碼塊 end loop; ";