2011-05-15 126 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