2011-08-25 73 views
12

使用JDBC(Oracle)我需要在两个表中插入大约1000行。类似这样的:Java JDBC - 多个准备好的语句批量插入

"INSERT INTO TABLE_A (A_ID, A_NAME, A_LAST_NAME) VALUES (MY_SEQUENCE.NEXTVAL, ?, ?)"; 
"INSERT INTO TABLE_B (B_ID, B_DESCRIPTION) VALUES (MY_SEQUENCE.CURRVAL, ?)"; 

问题是两个表都通过通用序列连接,因此语句的顺序很重要。

如果我只有一张桌子,这将是相当容易的。在这种情况下,我使用的代码:

String insert = "Insert into TABLE_A(A_ID, A_NAME, A_LAST_NAME) values(MY_SEQUENCE.NEXTVAL, ?, ?)"; 
conn.setAutoCommit(false); 
PreparedStatement ps = conn.prepareStatement(insert); 
for(MyObject obj : myCollection) { 
    ps.setString(1, obj.getName()); 
    ps.setString(2, obj.getLastName()); 
    ps.addBatch(); 
} 
ps.executeBatch(); 
conn.commit(); 
ps.close(); 

但这种方法只能用一个准备statment工作,因此只有一个插入。我怎样才能为这个问题提供解决方案?

回答

12

您可以尝试

PreparedStatement ps = conn.prepareStatement(insert, Statement.RETURN_GENERATED_KEYS); 
... 
ps.executeBatch(); 

然后

ResultSet rs = ps.getGeneratedKeys(); 
ps = conn.prepareStatement("INSERT INTO TABLE_B (B_ID, B_DESCRIPTION) VALUES (?, ?)"); 

for (int counter =0;rs.next(); counter++) { 
    ps.setInt(1,rs.getInt(0)); 
    ps.setString(2, myCollection.get(counter).getDescription()); 
    ps.addBatch(); 
} 
... 
1

如果我正确理解你的问题,你有NEXTVAL和CURRVAL的问题,因为CURRVAL可能会因其他数据库使用而改变? 如果是这样,您可以更改您的代码顺序如下:

currentNextVal = select NEXTVAL 
INSERT into table_a with currentNextVal as the id 
INSERT into table_b with the same currentNextVal 

难道我正确地理解你的问题?

+0

部分你是对的,但更复杂的问题是层出不穷约1000次在Java中一个执行这两个插入语句,以便在一个每行表将对应于另一个表中的一行(A_ID = B_ID)。如果它只有一个插入比我们可以使用addBatch(),如我在示例中所示,这将提高性能。但是似乎在java中使用两个准备好的语句是不可能的,这可能会导致性能问题。 – agav

+0

如果您从我的伪代码中使用相同的“currentNextVal”,您将实现它。尽管您可以分两批完成,但您不必一次执行它。 – IncrediApp