2016-12-01 3 views
0

Ich schaute auf viele Antworten, aber leider beantwortet keine meine Frage und ich kann immer noch nicht herausfinden, warum ich ResultSet closed bekomme. Hierjava.sql.SQLException: ResultSet auf sqlite geschlossen

ist der try Code-Schnipsel `s das Problem verursacht:

 System.out.println(" System Info! @CHKMD5Files(): Found pre-existing details: "+TOTAL); 

     Statement stmMD5 = null; 
     Connection connMD5 = null; 
     ResultSet rs_MD5 = null; 
     String RESULTMD5 = null; 

     try { 
      connMD5 = DriverManager.getConnection("jdbc:sqlite:" + bkpPATH+ hostname + ".db"); 
      stmMD5 = connMD5.createStatement(); 
      connMD5.setAutoCommit(false); 

      while (ROWID <= TOTAL) { 
       rs_MD5 = stmMD5.executeQuery("SELECT md5 FROM details WHERE ROWID = '"+ROWID+"';"); 
       RESULTMD5 = rs_MD5.getString("MD5"); 
       skipBuffer.write(RESULTMD5); 
       skipBuffer.newLine(); 
       skipBuffer.flush(); 
       ROWID++; 
       } 
      System.out.println(" System Info! @CHKMD5Files(): Done with try"); 

     } catch (Exception ex) { 
      System.out.println(" System Error! @CHKMD5Files (2): " + ex); 
      System.exit(5); 
     } finally { 
      if (stmMD5 != null){ 
       stmMD5.close(); 
       System.out.println(" System Info! @CHKMD5Files (2): Closing Statement(stmMD5)"); 
      } 
      if (connMD5 != null) { 
       connMD5.close(); 
       System.out.println(" System Info! @CHKMD5Files (2): Closing Connection(connMD5)"); 
      } 
      skipBuffer.close(); 
     } 
    } 

Sieht aus wie die while-Schleife auch nicht, da laufen, wenn ich print-Anweisung in der Schleife setzen gibt nichts zurück.

+0

An welchem ​​Punkt werden Sie diesen Fehler? –

+0

Könnten Sie die Stack-Trace des Fehlers hinzufügen? Es würde viel helfen –

+1

"Sieht so aus, als ob die while-Schleife nicht einmal läuft, denn wenn ich den Druck stament in die Schleife bringe, gibt nichts zurück." Es bedeutet, ROWID Variable gibt Ihnen das Problem. Also lege Code dafür. d.h. ein Abfrageteil, der das Ergebnis in ROWID speichert. –

Antwort

2

Wenn Sie eine ResultSet verwenden möchten, müssen Sie die next Methode aufrufen, zuerst den Zeiger des ResultSet in der ersten Reihe der Ergebnisse einstellen. Wie die Javadoc der Methode sagt:

Ein ResultSet-Cursor ist zunächst vor der ersten Zeile positioniert; der erste Aufruf der Methode macht die erste Zeile zur aktuellen Zeile; ...

Also, wenn Sie es nicht nennen, Sie zeigt nicht zu keinem Ergebnis und die getString Methode (verwendet in RESULTMD5 = rs_MD5.getString("MD5");) wird diese Ausnahme erzeugen. Fügen Sie also mindestens

rs_MD5.next() 

hinzu, bevor Sie die Ergebnisse extrahieren. Die next-Methode gibt einen booleschen Wert zurück, um anzuzeigen, ob die nächste Zeile erreicht werden kann oder nicht. Vielleicht möchten Sie also eine if -Anweisung hinzufügen, um zu überprüfen, ob dieser Wert wahr ist, bevor Sie einen Spaltenwert extrahieren, denn wenn next nicht zur nächsten Zeile gelangt (und false zurückgibt), wird der Zeiger auf keine gültige Zeile gesetzt Wenn Sie versuchen, auf die Ergebnisse zuzugreifen, erhalten Sie denselben Fehler (siehe den obigen Link zu Javadoc next).

Aber leider auch wenn Sie einen Anruf zu next hinzufügen würden, werden Sie den gleichen Fehler in der zweiten Iteration erhalten, weil Sie nicht das gleiche Statement -Objekt verwenden können verschiedene Abfragen auszuführen. Jedes Statement -Objekt kann nur eine ResultSet ergeben.
Um dies zu lösen, die Sie mindestens

rs_MD5 = stmMD5.executeQuery("SELECT md5 FROM details WHERE ROWID = '"+ROWID+"';"); 

mit

rs_MD5 = connMD5.createStatement().executeQuery(
     "SELECT md5 FROM details WHERE ROWID = '"+ROWID+"';" 
); 

ersetzen sollte Aber ich würde Sie sonst vorschlagen, weil eine neue Statement -object Schaffung ziemlich zeitaufwendig ist (jeder hat vor der Ausführung kompiliert werden). Da sich bei jeder Iteration nur das ROWID ändert, wäre es eine schreckliche Zeitverschwendung, dasselbe bei jeder Iteration erneut zu kompilieren. Verwenden Sie stattdessen eine PreparedStatement. Es ermöglicht Ihnen, eine Anweisung zu verwenden, die nur einmal kompiliert wird und die Sie mehrfach wiederverwenden können, indem Sie Parameter eingeben (nachdem sie kompiliert wurden). nutzen zu können, ein PreparedStatement Sie tun sollten:

Connection conn = ... //Connection to your database 
PreparedStatement ps = conn.preparedStatement("SELECT * FROM person WHERE name = ? AND age = ?"); 

//First search all persons with name "J.Baoby" and age = 5 
ps.setString(1, "J.Baoby"); 
ps.setInt(2, 5); 
ResultSet set1 = ps.executeQuery(); 
// Do something with it 
// .... 

//Now I need persons with name "Henry" and age = 25 
ps.setString(1, "Henry"); 
ps.setInt(2, 25); 
ResultSet set1 = ps.executeQuery(); 
// Do something with it 
// ... 

Die Art und Weise, diese Parameter zu injizieren, um den Index mit als erstes Argument eine setXXX Methode verwenden (Basis 1) des „?“ Sie möchten ersetzen und das zweite Argument ist der Wert.Die XXX wird durch den Typ des Werts ersetzt, den Sie injizieren möchten. Es gibt nur begrenzte Arten von Parametern, die Sie injizieren können. Überprüfen Sie zuerst die Java API, bevor Sie ein Objekt injizieren. Sie können weitere Informationen über PreparedStatement in der Java API oder on this site finden (mit einigen weiteren Beispielen).

Als letzt Ich mag würde hinzufügen, dass Sie alle Ihre (JDBC) Ressourcen schließen sollen (Connection, Statement, ResultSet, PreparedStatement, ...), wenn Sie sicher sind, dass Sie sie nicht mehr brauchen. Ressourcen, die Sie nicht freigeben, sind Ressourcenverschwendung, die Ihre JVM anderweitig zugewiesen haben könnte. Es ist eine schlechte Angewohnheit, deine Ressourcen nicht zu schließen, was zu einer Leistungseinbuße führen kann.

Viel Glück!

1

Vielen Dank für alle Ihre Antworten und für mich in den richtigen PATH Ich habe es geschafft, das Problem zu beheben, und es war, weil die ROWID hatte keine Daten am Anfang und das verursachte mir das Problem.

Die zusätzliche Aussage zu überprüfen, ob es resulved mein Problem ist leer:

   while (ROWID <= TOTAL) { 
       rs_MD5 = stmMD5.executeQuery("SELECT md5 FROM details WHERE ROWID = '"+ROWID+"';"); 
       if (!rs_MD5.next()) { 
        System.out.println(" System Info! @CHKMD5Files(): No data in rowid: "+ROWID); 
        ROWID++; 
       } else { 
        RESULTMD5 = rs_MD5.getString("MD5"); 
        skipBuffer.write(RESULTMD5); 
        skipBuffer.newLine(); 
        skipBuffer.flush(); 
        ROWID++; 
        rs_MD5.close(); 
       } 
      } 
+0

Dies gab mir einen Einblick, den ich nicht sehen konnte, danke –

Verwandte Themen