oracle 遷移 postgreSql 總結
一、遷移策略
1、pg大小寫不敏感,所有大寫的內容pg會自動識別或轉換為小寫,建表時,表名,字段名,序列名,索引名等,都用小寫,除大小寫以外與之前Oracle的命名規則一致。
2、字段類型選擇,涉及金額等最好使用numeric(n,m);涉及時間最好使用timestamp;字符串類型用varchar(n);較長字符串用varchar或text;主鍵類型int4或int8。
二.可能會出現的報錯和解決方案
1.No operator matches the given name and argument types. You might need to add explicit type casts.
原因:=兩邊的數據類型不同,varchar不能=number
解決:不改數據類型的情況下,使用CAST(* AS *)
2.時間計算使用date_part('second', now()-T.create_time)
3.For example, FROM (SELECT ...) [AS] foo.
原因:由於Oracle的rownum導致
解決:用ROW_NUMBER()OVER()) AS lineNum代替,分頁查詢試用封裝好的PG方法
4.Oracle start with遞歸查詢在PG報錯
原因:PG不支持start with
解決:使用WITH RECURSIVE方法查詢,具體要看sql復雜度
5.oracle的decode函數在PG不能用
解決:pg使用case when order_count = 0 then 1 else order_count end 代替decode
6.oracle的遞歸函數在PG不能用
StringBuffer sbSql = new StringBuffer(baseSql);
StringBuilder unionSql = new StringBuilder(unSql);
String baseSql = "WITH RECURSIVE trs AS ( select a.*,b.org_name sysOrgName from tb_org a left join tb_org_main b on a.org_id=b.org_id where 1=1 ";
//這里是需要有一個
unionSql.append(" ) SELECT * FROM trs ");
//合並sql
sbSql.append(" union all ").append(unionSql);
String unSql = "SELECT b.*,o.org_name sysOrgName FROM tb_org b LEFT JOIN tb_org_main o ON b.sys_org_id=o.org_id JOIN trs ON trs.hall_id = B.parent_org_id WHERE 1=1";
7 當前時間 SYSDATE 可全部使用current_timestamp替換
8 序列 SEQNAME.NEXTVAL替換為 NEXTVAL('SEQNAME')
9 固定值列 SELECT '1' AS COL1 SELECT CAST('1' AS TEXT) AS COL1
10 NVL NVL函數 NVL可以用COALESCE函數替換
11 類型自動轉換 Oracle某些情況下支持類型自動轉換 會出現類型不匹配等錯誤,需要在Java或者sql中進行類型轉換,使類型匹配
12 INSTR函數 instr('str1','str2') strpos('str1','str2')
13 外連接 Oracle可簡寫為(+) 用LEFT JOIN等語句替換
14 數據庫對象大小寫 不區分大小寫 創建數據庫對象時要小寫,這樣才不區分SQL的大小寫
15 同義詞 Oracle支持同義詞 用視圖代替