2011-05-15 123 views
0

我試圖編寫一個函數來更新我的數據庫中的兩個表。我收到了一個錯誤,我認爲這是由在集合中沒有更多行的結果集上調用next()引起的。 我想如果hasNext條件()會解決這個問題,但它不適用於結果集...JDBC ResultSet關閉語句

我得到的錯誤是'語句關閉後不允許操作'。

private void updateDatabase() throws Exception { 
     Connection conn = getConnection(); 
     PreparedStatement updateMovieStmt = conn.prepareStatement("INSERT INTO movies VALUES(null,?,null,null,null)", Statement.RETURN_GENERATED_KEYS); 
     PreparedStatement updateVideoStmt = conn.prepareStatement("INSERT INTO video_files VALUES(null,null,null,?,?)", Statement.RETURN_GENERATED_KEYS); 
     try { 
      for (Movie localMovie : getLocalMovies()) { 
       // fetch a local movie{ 
       boolean newMovie = true; 
       for (Movie dbMovie : getDatabaseMovies(conn)) { 
        newMovie = true; 
        Pattern p = Pattern.compile(localMovie.getTitlePattern(), Pattern.CASE_INSENSITIVE); 
        Matcher m = p.matcher(dbMovie.getTitle()); 
        // if it's already in the database not new movie... but is 
        // is it a new video rip????????????; 
        if (m.find()) { 
         System.out.println("DB movie: " + dbMovie.getTitle() + " matches localpattern of: " + localMovie.getTitlePattern()); 
         newMovie = false; 
         break; 
        } 
       } 
       if (newMovie == true && localMovie.getTitle() != null) { 
        updateMovieStmt.setString(1, localMovie.getTitle()); 
        updateMovieStmt.executeUpdate(); 
        // get new movie id and put into new video row 
        ResultSet rs = updateMovieStmt.getGeneratedKeys(); 
        if (rs.next()) { 
         updateVideoStmt.setBytes(1, localMovie.getHash()); 
         updateVideoStmt.setInt(2, rs.getInt(1)); 
         updateVideoStmt.executeUpdate(); 
        } 

       } 

      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } finally { 
      updateMovieStmt.close(); 
      updateVideoStmt.close(); 
      conn.close(); 
     } 
    } 

回答

1

如果你不使用批次(addBatch()/executeBatch()),也不清除參數(clearParameters()),那麼你應該創建循環內的語句,而不是在循環外。

將兩個conn.prepareStatement()行移入if (newMovie == true && localMovie.getTitle() != null)塊,最好用不同的方法重構。你目前的方法太過分了。

+0

[檢查你的這個答案](http://stackoverflow.com/questions/5149135/jdbc-statement-preparedstatement-per-connection) – sudmong 2011-05-16 01:16:39

+0

謝謝,你認爲updateMovie(連接conn,字符串標題)updateVideo ... 。會是一個合適的解決方案嗎? – 2011-05-16 01:39:34

+3

「每個連接只能有一個打開的語句,一旦你在同一個連接上創建一個新的語句並執行它,之前創建的語句將被關閉。」 - 「一次只能有一個公開聲明,一旦你創建一個新聲明,前一個將被關閉。」 - **這兩種說法都是錯誤的。** [正確答案在Mark Rotteveel的評論中這裏。](http://stackoverflow.com/a/5150085/269126) – Lumi 2012-03-29 07:25:07

1

每個連接只能有一個打開的語句。一旦你在同一連接上創建一個新的語句,先前創建的語句將被關閉

這對結果集是成立的,我們每個語句只能打開一個resultSet。通過連接,我們可以打開多個語句。

+1

是否對OP的具體問題做出回答,是否相關,以及@sudmong的聲明是否正確。 – Lumi 2012-03-29 07:28:35