【发布时间】:2016-07-15 13:25:11
【问题描述】:
我正在尝试在 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% 的批次在那里。
有人能解释一下为什么甲骨文会发生这种情况吗?有没有办法让它像在 SqlServer 上一样工作?
谢谢大家!
【问题讨论】:
标签: java sql-server oracle batch-file jdbc