我试图做的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一样工作?
谢谢大家!