2011-08-25 40 views
12

Sử dụng JDBC (Oracle) Tôi cần chèn khoảng nghìn hàng vào mỗi trong hai bảng. Một cái gì đó như thế này:Java JDBC - Chèn nhiều câu lệnh chuẩn bị sẵn sàng

"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, ?)"; 

Vấn đề là cả hai bảng được kết nối thông qua trình tự chung, do đó thứ tự các câu lệnh là quan trọng.

Sẽ khá dễ dàng nếu tôi chỉ có một bảng. Trong trường hợp đó tôi đã sử dụng mã:

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(); 

Nhưng cách tiếp cận này chỉ có thể làm việc với một chuẩn bị đã chuẩn bị và do đó chỉ có một Phụ trang. Làm thế nào tôi có thể cung cấp một giải pháp cho vấn đề này?

Trả lời

12

Bạn có thể thử

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

sau đó

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

Nếu tôi hiểu vấn đề của bạn một cách chính xác, bạn có vấn đề với NEXTVAL và CURRVAL vì CURRVAL có thể thay đổi do sử dụng DB khác? Nếu vậy, bạn có thể thay đổi mã của bạn để theo thứ tự:

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

Did Tôi hiểu vấn đề của bạn một cách chính xác?

+0

Nhiều bạn là đúng, nhưng vấn đề phức tạp hơn là để thực hiện cả hai tuyên bố chèn TRÊN JAVA cái khác khoảng 1000 lần để mỗi hàng trong một bảng sẽ tương ứng với một hàng trong bảng khác (A_ID = B_ID). Nếu nó chỉ là một chèn hơn chúng ta có thể sử dụng addBatch() như tôi hiển thị trong ví dụ và điều này sẽ làm tăng hiệu suất. Nhưng có vẻ như không thể với hai câu lệnh chuẩn bị trong java, và điều này có thể gây ra các vấn đề về hiệu năng. – agav

+0

Nếu bạn sử dụng cùng một "currentNextVal" từ mã giả của tôi, bạn sẽ đạt được nó. Bạn không cần phải thực hiện nó trong một lô, mặc dù bạn có thể làm điều đó trong 2 lô ... – IncrediApp

Các vấn đề liên quan