2011-05-15 12 views
0

私のデータベースに2つのテーブルを更新する関数を記述しようとしています。私は、私はセット内の行がない結果セットの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

"接続ごとに開いているステートメントは一度に1つしかできません。同じ接続で新しいステートメントを作成して実行すると、以前に作成されたステートメントは閉じられます。 - "一度に1つの文しか開くことはできません。新しい文を作成すると、前の文が閉じられます。" ** **これらの声明は間違っています** **正解はMark Rotteveelのコメントにあります。](http://stackoverflow.com/a/5150085/269126) – Lumi

1

接続ごとに1つのオープンステートメントのみを持つことができます。同じ接続で新しいステートメントを作成すると、以前に作成されたステートメントが閉じられます。

これは、1つのステートメントにつき1つのresultSetしかオープンできないresultSetに当てはまります。接続によって、複数のステートメントを開くことができます。

+1

OPの具体的な問題に対する答えかどうかは関係しており、@ sudmongの記述は正しい。 – Lumi

関連する問題