从oracle迁移带clob字段的表数据至postgresql

在oarcle的sql脚本中字段长度超过4000执行会有异常,而在postgresql中超过4000仍可以正常执行,产品同时支持多个数据库,如oracle和postgresql,在基础数据较多时,只能通过导出基础数据相关表的dmp或backup文件进行升级部署。开发的时候以oracle作为开发库,需要将基础数据弄到postgresql制作backup文件,通过程序直接读oracle表写到postgresql。

步骤:

1、修改oracle和postgresql库的ip、用户名和密码;

2、修改库表列表;

3、运行;

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)
        {
            /*1、清理目标表*/
            dstStmt.execute("truncate table " + table);
            
            /*2、查询源表字段拼接预处理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);
            
            /*3、读取源表数据插入目标表,每千条提交一次*/
            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) + "毫秒。");
}
时间: 2024-10-18 19:47:51

从oracle迁移带clob字段的表数据至postgresql的相关文章

【Oracle】给clob字段插入数据

// 插入 //OracleCommand cmd = "insertInto into GIS_PolygonPoint(PCode,PointColl) values('140134', :var)"; // 修改 //OracleCommand cmd = new OracleCommand("update yd_line set coord=:coordstr where lineid=" + LineId.ToString(), conn); string

给Oracle数据库中CLOB字段插入空值

遇到往ORACLE数据库中插入数据时总是报ORA-01084 invalid argument in OCI call错误,经分析是因为表中的一个字段类型为CLOB,并且可为空,当在给该字段插入空值时引发的该错误.后来判断是否为空值,如果为空值使用DBNull.Value,以此解决了该问题. Null 指的是无效的对象引用:而 DBNull 是一个类, DBNull.Value 是它唯一的实例 .DBNull 的实例 DBNull.Value是数据库表中的空数据在 .Net 代码中的表现形式.我

oracle迁移到mysql分库分表方案之——ogg(goldengate)

之前文章主要介绍了oracle 迁移到mysql,主要是原表原结构迁移,但是实际运维中会发现,到mysql以后需要分库和分表的拆分操作,这个时候,用ogg来做,也是很强大好用的.主要结合ogg的2个参数 参数1:filterUse a FILTER clause to select rows based on a numeric value by using basic operators or one or more Oracle GoldenGate column-conversion fu

Oracle导出包含clob字段的sql脚本工具

之前工作中遇到生产环境不允许导入Oracle的dmp文件,只能导入sql脚本,但是表中存在clob字段,直接用plsql工具无法导出clob字段,用了下dbvisualizer可以直接导出,亲测可用. dbvisualizer是一款十分好用的数据库工具,支持数据库AmazonRedShift.DB2LUW.Exasol.H2.Informix.JavaDB/Derby.Microsoft SQL Server.MIMERSQL.MySQL.Netezza.NuoDB.Oracle.Postgre

OGG能否复制迁移包含CLOB字段的table

Oracle的官方文档“Can GoldenGate Replicate An Oracle Table That Contains Only CLOB Column(s)? (文档 ID 971833.1) 给出了解释:OGG并不支持CLOB的复制迁移.详见如下: APPLIES TO: Oracle GoldenGate - Version 4.0.0 and laterInformation in this document applies to any platform. Questio

ORACLE+PYTHON实战:复制A表数据到B表

最近在学习python ,看到了pythod的oracle,不仅可以一次fetch多条,也可以一次insert多条,想写一个复制A表数据到B表的程序来看看实际效率能不能提高.写完发现,非常惊艳!效率提升了近一倍! 当然可能会认为这个没有实际意义,其实不然. 从A表复制数据到B表有很多中方法,一般直接insert即可: insert into tableA select * from tableB ; 但是当数据量非常大时,到达上亿水准的时候,这样做就很郁闷了,因为本身会跑很慢,又看不到进度,偶尔

ORACLE清除某一字段重复的数据(选取重复数据中另一个字段时期最大值)

需求:资产维修表中同一资产可能维修完继续申请维修,这时候维修状态需要根据最近的维修时间去判断维修状态,所以同一资产ID下会出现重复的数据(维修审批通过,维修审批未通过),或者可能不出现(未申请维修),所以需要查询资产维修表中未重复的数据和重复的数据中申请维修日期最近的数据,方法如下: 资产表如下: 1.资产维修中所有的数据select * from ASSET_MAINTAIN t 结果如下: 2.资产维修中可能相同的数据select a.*  from ASSET_MAINTAIN a inn

C#实现Oracle数据库插入clob字段类型数据

public static void InsertWithLob(OracleConnection conn)        {            if (conn!= null && conn.State == ConnectionState.Open)            {                try                {                    string sqlText = "insert into tb_nclob(id,n

sql实现从两个表获取字段组成表数据再插入到函数表中

实现此效果说起来比较难以说明,我这里还是先将实现的效果已图的形式展示一下吧. 这是两个表的设计.我想实现的效果举个例子,以查询secretaryCharge为例: 点击"市级",我将查询到市级一下所有"区级"的secretaryCharge数目,并通过organizations中的fullName来作为名字,查到的统计数目作为值.得到的效果便是如下图所示: 具体实现sql语句就是用到join on,sql语句具体如下: insert @result(fullName