2016-07-15 50 views
0

我试图做的SqlServer和Oracle批量插入,在下面的测试代码中实现不同的:JDBC插入批次工作的SqlServer和Oracle

public class TesteBatch { 

public static void main(String[] args) throws ClassNotFoundException { 

    Connection con = getConnection(); 
    try { 
     con.setAutoCommit(false); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 


    PreparedStatement psInsert = criaPs(con); 

    Date time = Calendar.getInstance().getTime(); 

    for (int i = 1; i <= 50000; i++) { 
     try { 

      psInsert.setInt(1, i); 

      psInsert.setTimestamp(2, new Timestamp(time.getTime())); 
      psInsert.addBatch(); 
     } catch (SQLException e) { 
      System.out.println("Erro inserindo " + i); 
     } 
    } 

    try { 
     int[] executeBatch = psInsert.executeBatch(); 
     System.out.println(Arrays.toString(executeBatch)); 
     psInsert.close(); 
     con.close(); 
    } catch (BatchUpdateException e) { 
     e.printStackTrace(); 
     System.out.println(Arrays.toString(e.getUpdateCounts())); 

    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 

} 

private static PreparedStatement criaPs(Connection con) { 
    try { 
     return con.prepareStatement("insert into tester values (? , ?)"); 
    } catch (SQLException e) { 
     throw new RuntimeException(e); 
    } 
} 

private static Connection getConnection() { 
    try { 
     String url = "jdbc:oracle:thin:@BI_ENS:1521:xe"; 
     Class.forName("oracle.jdbc.OracleDriver"); 
     return DriverManager.getConnection(url,"xxxx", "xxxx"); 
    } catch (ClassNotFoundException | SQLException e) { 
     throw new RuntimeException(e); 
    } 
} 

}

的代码数据插入具有主键ID和时间戳的Tester表。

我想要做的就是插入到数据库中的方式,即使批处理中的某些数据已经存在,那里没有插入的数据也会被插入,因为主键约束被违反而抛出BatchUpdateException 。

我正在测试一批有50.000个条目,其中50%已经在数据库中。

使用SqlServer它按预期工作,抛出异常,但未被复制的数据仍然插入到数据库中,最后所有50k注册表都在数据库中。

虽然它不适用于Oracle,但会发生异常并且批处理中没有任何内容被插入,即使数据库上不存在的数据也是如此。最后只有50%的批次在那里。

有人可以解释为什么在Oracle上发生这种情况吗?有没有办法让它像SqlServer一样工作?

谢谢大家!

回答