2011-05-15 6 views
0

데이터베이스에 2 개의 테이블을 업데이트하는 함수를 작성하려고합니다. 나는 내가 set()에 더 이상 행이없는 결과 집합에서 next()를 호출하여 발생한다고 생각하는 오류가 발생했습니다. hasNext()에서 if 조건을 수정하려고했지만 결과 집합에서 사용할 수 없습니다. ...JDBC ResultSet closed 문

오류가 발생하는 이유는 '문을 닫은 후에 작업이 허용되지 않습니다.'입니다. 당신이하지 루프 외부 루프 내부의 문을 작성해야

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

+0

감사합니다. updateMovie (Connection conn, String title) updateVideo ...라고 생각하십니까? 적절한 솔루션이 될 것입니까? –

+3

"연결 당 한 번에 하나의 열려있는 명령문 만 가질 수 있습니다. 동일한 연결에서 새로운 명령문을 만들고 실행하면 이전에 작성된 명령문이 닫힙니다." - "한 번에 하나의 문장 만 열 수 있습니다. 새 문장을 만들면 이전 문장이 닫힙니다." - **이 두 진술은 모두 잘못되었습니다. ** [정답은 Mark Rotteveel의 코멘트입니다.] (http://stackoverflow.com/a/5150085/269126) – Lumi

1

연결 당 하나의 개방형 명령문 만 가질 수 있습니다. 동일한 연결에서 새 Statement를 작성하면 이전에 작성된 Statement를 닫습니다.

이는 하나의 명령문에 대해 하나의 결과 세트 만 가질 수있는 resultSet에 적용됩니다. 연결을 통해 여러 문장을 열어 볼 수 있습니다.

+1

OP의 구체적인 문제에 대한 대답 이건 아니건 관계가 있고 @sudmong이 (가) 진술 한 문구가 맞습니다. – Lumi