JDBC在SqlServer和Oracle上插入批处理工作不同

时间:2016-07-15 13:25:12

标签: java sql-server oracle batch-file 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上一样工作?

谢谢大家!

1 个答案:

答案 0 :(得分:0)

根据oracle文档http://docs.oracle.com/cd/E11882_01/java.112/e16548/oraperf.htm#JJDBC28767,这是oracle processess批处理的方式:

  

注意:   批处理的执行始终会以生成错误的批处理的第一个元素停止。