從oracle遷移帶clob字段的表數據至postgresql

在oarcle的sql腳本中字段長度超過4000執行會有異常,而在postgresql中超過4000仍能夠正常執行,產品同時支持多個數據庫,如oracle和postgresql,在基礎數據較多時,只能經過導出基礎數據相關表的dmp或backup文件進行升級部署。開發的時候以oracle做爲開發庫,須要將基礎數據弄到postgresql製做backup文件,經過程序直接讀oracle表寫到postgresql。java

步驟:
sql

一、修改oracle和postgresql庫的ip、用戶名和密碼;數據庫

二、修改庫表列表;oracle

三、運行;app

public static void main(String[] args) throws Exception
{
    long t0 = System.currentTimeMillis();
    Class.forName("oracle.jdbc.driver.OracleDriver");
    Class.forName("org.postgresql.Driver");
    
    Connection srcCon = null, dstCon = null;
    Statement srcStmt = null, dstStmt= null;
    PreparedStatement ps = null;
    
    try{
        /*建立鏈接*/
        srcCon = DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.12:1521:orcl", 
                "h2do", "h2do");
        dstCon = DriverManager.getConnection("jdbc:postgresql://192.168.1.23:5432/h2do", 
                "postgres", "postgres");
        
        srcStmt = srcCon.createStatement();
        dstStmt = dstCon.createStatement();
        
        /*庫表列表*/
        String[] tables = new String[]{
                "h2do", 
                "e2say"
                }; 
        
        /*逐表處理*/
        for(String table : tables)
        {
            /*一、清理目標表*/
            dstStmt.execute("truncate table " + table);
            
            /*二、查詢源表字段拼接預處理SQL語句*/
            ResultSet rs = srcStmt.executeQuery("select * from " + table);

            StringBuilder sql1 = new StringBuilder("insert into " + table + "(");
            StringBuilder sql2 = new StringBuilder(") values (");
            ResultSetMetaData rsmd = rs.getMetaData();
            for(int col = 1; col <= rsmd.getColumnCount(); col++)
            {
                if(col > 1){
                    sql1.append(",");
                    sql2.append(",");
                }
                sql1.append(rsmd.getColumnName(col).toLowerCase());
                sql2.append("?");
            }
            String sql = sql1.toString() + sql2.toString() + ")";
            System.out.println(sql);
            
            /*三、讀取源表數據插入目標表,每千條提交一次*/
            int rows = 0;
            ps = dstCon.prepareStatement(sql);
            while(rs.next())
            {
                for(int col = 1; col <= rsmd.getColumnCount(); col++)
                {
                    if(rsmd.getColumnType(col) == Types.CLOB){
                        ps.setString(col, rs.getString(col));
                    }else{
                        ps.setObject(col, rs.getObject(col));
                    }
                }
                
                ps.addBatch();
                
                rows++;
                
                if(rows%1000 == 0)
                {
                    ps.executeBatch();
                    dstCon.commit();
                    
                    ps.clearBatch();
                    rows = 0;
                }
            }
            if(rows > 0){
                ps.executeBatch();
                dstCon.commit();
            }
            ps.close();
            
            System.out.println("耗時:" + (System.currentTimeMillis() - t0) + "毫秒(" + table + ")。");
        }
        
    }finally{
        try{if(null != srcStmt)srcStmt.close();}catch(Exception e){}
        try{if(null != srcCon )srcCon.close(); }catch(Exception e){}
        try{if(null != dstStmt)dstStmt.close();}catch(Exception e){}
        try{if(null != dstCon )dstCon.close(); }catch(Exception e){}
    }
    
    System.out.println("總耗時:" + (System.currentTimeMillis() - t0) + "毫秒。");
}
相關文章
相關標籤/搜索