2011-08-08 23 views
5

Tôi đang sử dụng câu lệnh SELECT để lấy dữ liệu từ một bảng và sau đó chèn nó vào một bảng khác. Tuy nhiên dòng "stmt.executeQuery (truy vấn);" đang chèn dòng đầu tiên từ bảng rồi thoát. Khi tôi bình luận dòng này ra, vòng lặp while lặp qua tất cả các dòng in chúng ra. Stacktrace không hiển thị bất kỳ lỗi nào. Tại sao chuyện này đang xảy ra?Tại sao câu lệnh While (rs.next()) kết thúc sau lần lặp thứ nhất?

try{     
    String query = "SELECT * FROM "+schema_name+"."+table; 

    rs = stmt.executeQuery(query); 

    while (rs.next()) { 

     String bundle = rs.getString("BUNDLE"); 
     String project_cd = rs.getString("PROJECT_CD"); 
     String dropper = rs.getString("DROPPER"); 
     String week = rs.getString("WEEK"); 
     String drop_dt = rs.getString("DROP_DT").replace(" 00:00:00.0",""); 

     query = "INSERT INTO INDUCTION_INFO (BUNDLE, PROJECT_CD, DROPPER, WEEK, DROP_DT) " 
       + "VALUES (" 
       + bundle+"," 
       + "'"+project_cd+"'," 
       + dropper+"," 
       + week+"," 
       + "to_date('"+drop_dt+"','YYYY-MM-DD'))"; 

     System.out.println(query); 

     stmt.executeQuery(query); 
    } 
}catch(Exception e){ 
    e.printStackTrace(); 
} 
+0

Hm ... thực sự tôi không biết nếu gọi 'executeUpdate()' trên một câu lệnh đóng các câu lệnh trước đó 'ResultSet'. Và tôi quá lười để kiểm tra ngay bây giờ ... –

+1

Câu hỏi cụ thể đã được trả lời, nhưng như một quan sát: bạn nên sử dụng một câu lệnh chuẩn bị và thay đổi các biến liên kết mỗi lần thay vì xây dựng một chèn mới với các giá trị hard-coded in (Nó có vẻ giống như một nơi không chắc chắn để có được một SQL injection, nhưng phụ thuộc ai có thể đặt các mục trong bảng nguồn ...). Nhưng tại sao không chỉ làm điều đó trong một hit với một lựa chọn-như-chèn, thay vì looping? –

Trả lời

24

Bạn đang tái sử dụng Statement đã được sử dụng để sản xuất rs trên dòng cuối cùng của vòng lặp của bạn.

Điều này sẽ đóng ResultSetrs. Như stated in the documentation:

Một đối tượng ResultSet được tự động đóng lại khi đối tượng Statement mà tạo ra nó được đóng lại, lại thực hiện, hoặc sử dụng để lấy kết quả tiếp theo từ một chuỗi nhiều kết quả.

Bạn cần sử dụng đối tượng Statement thứ hai để thực hiện các tuyên bố INSERT.

9

Statement đối tượng chỉ có thể thực hiện một việc tại một thời điểm, vì vậy khi bạn thực hiện INSERT, bạn làm mất hiệu lực số ResultSet mà nó tạo ra. Bạn cần phải tạo đối tượng Statement thứ hai để thực hiện INSERT.

Từ Statement documentation: "Theo mặc định, chỉ có một đối tượng ResultSet trên mỗi đối tượng Statement có thể mở cùng một lúc. Do đó, nếu đọc một đối tượng ResultSet được xen kẽ với nhau, thì mỗi đối tượng phải được tạo bởi Các đối tượng Statement khác nhau. Tất cả các phương thức thực hiện trong giao diện Statement đều đóng một đối tượng ResultSet hiện tại của statment nếu một đối tượng mở tồn tại. "

1

nếu bạn sử dụng cùng một câu lệnh, nó sẽ làm mất hiệu lực tập kết quả trước đó. Bạn nên sử dụng một câu lệnh khác để thực hiện cập nhật/chèn.

1

Đây là từ các tài liệu Java của giao diện Statement:

Theo mặc định, chỉ có một đối tượng ResultSet mỗi đối tượng Statement có thể mở cùng một lúc.

Vì vậy, bạn tốt hơn sử dụng một giây Statement hoặc thậm chí tốt hơn một PreparedStatement.

Và để thực thi câu lệnh SQL INSERT, bạn nên sử dụng executeUpdate() thay vì executeQuery().

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