這幾天把項目的存儲過程從oracle遷移到了達夢8,記錄一下心得。國產數據庫作到這樣,已經算很了不得了,跟oracle兼容性確實很高。mysql
但仍是有一些細節沒作好,主要是出錯提示不友好,另一個網上的資料也不多,出問題很差定位。(達夢的錯誤碼比較簡單,就是一個負數,不像oracle是ora-錯誤碼,在百度時輸入一個負數搜索信息,跟一長串錯誤碼搜索效率差很遠)sql
準備工做:數據庫
1 達夢的數據庫管理工具默認不顯示行號,也不能自動補全,須要手動設置。行號設置方法:在sql編輯頁面,左側空白豎欄(通常編輯器顯示行號的地方)右擊,選擇」顯示行號「。自動補全設置方法:在sql編輯頁面空白處右擊,選擇「選項」,彈出的界面展開「查詢分析器」,進入「編輯器」配置頁面,選中「啓用SQL輸入助手」安全
2 裝完達夢數據庫後,須要啓動oracle兼容模式sp_set_para_value(2,‘COMPATIBLE_MODE’,2);,另外,須要啓動dbms_job包,SP_INIT_JOB_SYS(1)。改完設置後記得重啓。oracle
遷移碰上的問題及解決方法:編輯器
1 使用達夢的數據庫遷移工具,把oracle的用戶總體遷移到達夢後,是變成一個模式,而不是用戶,使用起來不方便。ide
解決方法:達夢數據庫有用戶和模式兩個概念,庫表和存儲過程等是建在模式下面的,而用戶則是獨立的,與安全和權限功能掛鉤,這跟mysql比較像。達夢的用戶進行數據庫操做時,默認使用同名的模式,想訪問其它模式的元數據,須要顯式加模式名。因此爲了跟oracle保持一致,在遷移完後,須要手工給達夢添加oracle同名用戶。函數
2 遷移後發現有一些存儲過程,包等缺失。工具
解決方法:遷移工具作得不是太好,有一些oracle數據庫的元素是不會自動遷移的,須要手工處理。例如oracle的type(達夢叫「類」),一些包含達夢數據庫關鍵字的存儲過程等。(在遷移日誌裏面沒報錯的,但也是可能沒遷成功,須要仔細檢查)日誌
3 oracle建SEQUENCE裏面的關鍵字MINVALUE達夢不支持
4 達夢的關鍵字比oracle多不少,例如CONTEXT,bool,class,decode這些,oracle不是關鍵字,但達夢是。
解決方法:給這些使用了關鍵字的字段名或者變量名加上"",而且轉換成大寫就能夠了。例如"CLASS"
5 建了包,提示建立成功,編譯有錯,但沒有具體說明錯誤地方。
解決方法:能夠在後面增長語句:alter package q$err_mgr compile;
6 提示「第3156 行附近出現錯誤[-3719]: 非法的基類名[DBMS_SQL]」
解決方法:首先確認DBMS_SQL包是否啓用(在左側「工具包」菜單右鍵,選擇啓用)。若是啓用了後還報這個錯,則須要檢查是否使用了某些DBMS_SQL的類型或者函數,在oracle有,可是在達夢沒有的。
7 編譯包時提示「第3494 行附近出現錯誤[-2193]:無效的方法名[func_name]"
解決方法:這種提示緣由有不少,多是肯定在包裏面沒有定義這個func_name,也多是func_name不在包頭裏面聲明,但在初始化代碼裏面調用。(oracle容許只在包體裏面定義,達夢不容許)。也多是調用func_name的函數跟func_name都不在包頭聲明,可是在包體定義時,func_name出現位置比調用處更晚,在達夢這種是不容許的。
8 regexp系統函數提示「參數不兼容」
解決方法:達夢的regexp系統函數的參數名與oracle的不同,若是原來在oracle指定了參數名,搬到達夢編譯時容易出現這個錯。改成非顯示命名函數參數就好。
9 出現提示「第646 行附近出現錯誤[-3325]:包/對象[package_name]解析失敗」,但646行代碼是空白行
解決方法:達夢的報錯位置不是太準確,這種狀況下通常是上下文語法解析出現問題致使的。我碰到比較多的狀況是在for循環語句裏面使用了case when ... end子句。達夢8對於case when支持不太好,容易把case when的end關鍵字與begin配對了,致使語法錯亂。個人解決方法是使用decode改寫case when
10 報錯提示「沒法解析的成員訪問表達式[XXX] 」
解決方法:這類錯誤主要是由於其它包之類的編譯失效致使,須要具體分析再解決。有時會出現循環引用的狀況(a包引用b包的函數,b包引用a的函數),達夢支持不太好,編譯a時提示b的函數有問題,編譯b時提示a的函數有問題。個人解決方法是創建一個c包,把一些代碼從a和b抽出來,避免循環引用。大部分時候循環引用是能夠編譯過的,也多是因爲其它錯誤引發包編譯不過,可是系統沒提示好。這種狀況下只要解決了另外的錯誤,這個循環引用編譯失敗的問題也就解決了。
11 提示「非法的基類名[ROWID]」
解決方法:個人代碼裏面使用了rowid類型變量,我直接改爲number了
12 達夢對於重載(覆蓋)支持不太好
解決方法:oracle裏面兩個同名函數,參數同樣,只是一個是IN類型參數 ,一個是IN OUT參數,是被認爲是兩個不一樣類型的函數,能夠正常重載。但達夢認爲是同一個函數,編譯時會出錯。解決辦法是把其中一個更名。另外,oracle裏面varchar2(64),varchar2(1024)是兩種不一樣的類型,能夠支持重載兩個函數,參數爲這兩種類型,但在達夢不支持。oracle裏面同名的CONSTANT變量定義,後出現的會覆蓋先出現的。但在達夢裏面不支持。提示「錯誤號: -2120 無效的變量名」
遷移過程當中也許還會碰上其它問題,處理原則是查官方幫助文檔(在幫助菜單下面搜索,同時在安裝目錄下面也有不少pdf文件介紹),查百度,問官方支持。(我另了達夢的技術支持羣,羣裏的南網工做人員仍是挺熱心的)
有時官方支持也搞不清楚,須要本身經過刪減代碼,慢慢定位問題,再本身猜想出錯緣由並嘗試解決。
另外,以前有人寫過一份教程《oracle遷移達夢常見問題彙總》 https://www.cndba.cn/foucus/article/4142 ,裏面介紹了很多遷移的經驗,也是值得借鑑的。