Zum Inhalt springen

SQLException: Operation not allowed after ResultSet closed - ist aber offen


Empfohlene Beiträge

Geschrieben

Hi@all

Erstmal der code:

	SpaceMigrationTool() throws Exception{


		// MySQL part----------

		// declares the database connection

		Connection conn = null;

		Class.forName(DRIVER);



        // CONNECTION ---------------

        try{

        	try { //ends witch catch SQLException


            	//connecting...

    			conn = DriverManager.getConnection(dbHost

    												+dbName

    												+"?user="+dbUsr

    												+"&password="+dbPwd);


    			stmt = conn.createStatement();




    		    fillForumTable();


    		    System.out.println("Programmende");



    		    //end of everything that needs the MySQL connection conn

            } catch (SQLException ex) {

    			// handle any errores

    			// declares the PrintWriter "write"

            	do{

            		System.out.println("SQLException: " + ex.getMessage());

        			System.out.println("SQLState: " + ex.getSQLState());

        			System.out.println("VendorError: " + ex.getErrorCode());

            	}while(ex.getNextException()!=null);



    		}

        } finally {

            if (res != null) {

                try {res.close();} catch (SQLException ex) {}

                res = null;

            }


            if (stmt != null) {

                try {stmt.close();}catch (SQLException ex) {}//do nothing

                stmt = null;

            }

        	if(conn != null){

        		try{conn.close();}catch (SQLException ex){}

        	}

        }


	}


	protected ResultSet mysqlSel(String SQLSTATEMENT) throws Exception{

		ResultSet rs;


		if(stmt.execute(SQLSTATEMENT)){

			rs = stmt.getResultSet();

			return rs;

		} else {

			throw new Exception("SELECT Abfrage fehlgeschlagen. Ungültige Syntax oder keine Datenbankverbindung");

		}

	}//end of function mysqlSel


	protected boolean mysqlInsert(String SQLSTATEMENT) throws SQLException{	

		if(stmt.execute(SQLSTATEMENT)){

			return true;

		} else {

			return false;

		}

	}//end of function mysqlInsert


	protected boolean fillForumTable() throws Exception{

		//try{

		SQLSTMT = "SELECT title_clean, parentid FROM forum;";


		//execute query

	     	 ResultSet res = mysqlSel(SQLSTMT);


	    	 ResultSetMetaData rsmd = res.getMetaData();

	    	 int n = rsmd.getColumnCount();

	    	 System.out.println("Anzahl der Felder: "+n);


	    	 int lines=0;

	    	 String[] resStr = new String[n+1];

	    	 while(res.next()){

	    		 sb.append("Datensatz "+lines+": ");

	             for(int i=1; i<=n; i++ ){// Attention: first column with 1 instead of 0

	            	 resStr[i] = res.getString(i);

	            	 sb.append(resStr[i]+";");

	             }

	             SQLSTMT="INSERT INTO `spacequadrat`.`archv_forum` (`forumid` ,`title` ,`parent`) VALUES (NULL, '"+resStr[1]+"', '"+resStr[2]+"');";


	            	 if(mysqlInsert(SQLSTMT)){

	            		 sb.append("Eintrag fehlgeschlagen!!!!!!!!!!!\r\n");

		             }else {

		            	 sb.append("Erfolgreich eingetragen\r\n");

		             }

	             System.out.println(sb.toString());

	             lines++;

	           }

	    	return true;

	}

Im Titel steht schon die Fehlermeldung:

Hier mal etwas ausgabe:

Anzahl der Felder: 2

Datensatz 0: Intern;-1;Erfolgreich eingetragen

SQLException: Operation not allowed after ResultSet closed

SQLState: S1000

VendorError: 0

Fehler tritt bei while(res.next()) in fillForumTable auf

Wie ihr sehr wird angemeckert das das ResultSet angeblich closed ist was aber an dieser Stelle überhaupt nicht sein darf weil while(res.next()) erfüllt sein müsste denn es gibt 57 Datensätze (Es sind auch im ResultSet 57 Rows angegeben).

Wie ihr seht schliesse ich erst alles nachdem der Konstruktor durchgelaufen ist mit einem finally.

Hat jemand eine Idee was ich falsch mache?

Vielen Dank für eure Hilfe!

Geschrieben

Die Methode next() prüft nicht, ob es einen Datensatz gibt, sondern springt zum nächsten Datensatz. Du hast also überhauptkeine Bedingung angegeben. Sollte eigentlich mit res.next() != null funktionieren.

gr33tz

Raphael

Geschrieben (bearbeitet)

Ich hab mir die Funktion angeguckt und da steht drin dass sie true zurückgibt wenn ein weiterer Result-Set vorhanden ist und geht auf ihn weiter.

Das wird auch in vielen Beispielen so verwendet aber ich probier deinen Vorschlag natürlich trotzdem gerne aus.

Vielen Dank!

*Edit: The operator != is undefined for the argument type(s) boolean, null sagt mir Eclipse wenn ich das einfüge.

Hier mal die Beschreibung der Methode

boolean java.sql.ResultSet.next() throws SQLException

next

boolean next()

throws SQLException

Moves the cursor froward one row from its current position. A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.

When a call to the next method returns false, the cursor is positioned after the last row. Any invocation of a ResultSet method which requires a current row will result in a SQLException being thrown. If the result set type is TYPE_FORWARD_ONLY, it is vendor specified whether their JDBC driver implementation will return false or throw an SQLException on a subsequent call to next.

If an input stream is open for the current row, a call to the method next will implicitly close it. A ResultSet object's warning chain is cleared when a new row is read.

Returns:

true if the new current row is valid; false if there are no more rows

Throws:

SQLException - if a database access error occurs or this method is called on a closed result set

Ich weis nicht ob ich das so schonmal erwähnt hatte:

Das ganze läuft einmal durch beim zweiten mal bekommt er den Error.

Bearbeitet von Ghostridah
Geschrieben
Ich hab mir die Funktion angeguckt und da steht drin dass sie true zurückgibt wenn ein weiterer Result-Set vorhanden ist und geht auf ihn weiter.

....

*Edit: The operator != is undefined for the argument type(s) boolean, null sagt mir Eclipse wenn ich das einfüge.

Nuja, nen Boolean ist nunnmal nicht null, genauso wie ein int nicht null ist. ...

Aber DDas nur am Rande.

if (rs.next()) {

handleData

} 

Geschrieben

Danke für deine Antwort.

Allerdings sollte es doch auch mit while() funktionieren wenn es mit if gehen würde oder sehe ich das falsch?

Ausserdem ist das nicht die richtige Kontrollstruktur in dem Fall ich möchte das ganze ja nicht einmal ausführen sondern eben solange .next() true zurückgibt, also es Werte gibt.

Geschrieben

ResultSet res = mysqlSel(SQLSTMT);


//...


if(mysqlInsert(SQLSTMT)){
Überschreibst du da nicht das ResultSet von stmt?! Vielleicht wirds daher geclosed. btw:

String[] resStr = new String[n[COLOR="Red"]+1[/COLOR]];

	    	 while(res.next()){

	    		 sb.append("Datensatz "+lines+": ");

	             for(int i[COLOR="Red"]=1[/COLOR]; i<=n; i++ ){// Attention: first column with 1 instead of 0

	            	 resStr[i] = res.getString(i);

*hüstel* :rolleyes:

Geschrieben

Ah super das war ein guter Hinweis! Vielen Dank!

Ich überprüf das mal gleich.

Jaja der Code ist nicht ganz so sauber wie er sein sollte... :D

Bin noch nicht so erfahren dass ich ohne Workarounds manchmal auskomme.

Geschrieben

Um das nochmal klar zustellen, was hier noch so über die next()-Methode gesagt wurde, obwohl das ja eigentlich alles in dem Dokumentationsabschnitt steht, den Ghostridah ja schon schlauerweise gepostet hat.

Die Methode next() bewegt nur den Cursor im ResultSet und gibt nicht irgendeinen Wert der aktuellen Zeile zurück. Aber dabei überprüft er natürlich auch, ob überhaupt noch Zeilen vorhanden sind, auf die er springen kann.

Wenn er also auf eine verwertbare Zeile weitergesprungen ist, gibt er true zurück, wenn es jedoch keine verwertbare Zeile, also in dem Fall die Zeile nach der letzten Zeile ist, dann gibt er false zurück, und die Verarbeitung sollte abgebrochen werden.

Es ist also vollkommen legitim diese Verarbeitung in einer while -Schleife abzuarbeiten, ohne next() != null und ohne extra If-Bedingungen.

Das Problem hier liegt eindeutig darin, dass das ResultSet geschlossen wurden und damit die next()-methode nicht funktionieren kann.

Geschrieben
Danke für deine Antwort.

Allerdings sollte es doch auch mit while() funktionieren wenn es mit if gehen würde oder sehe ich das falsch?

Ausserdem ist das nicht die richtige Kontrollstruktur in dem Fall ich möchte das ganze ja nicht einmal ausführen sondern eben solange .next() true zurückgibt, also es Werte gibt.

Jap, kann man im while nutzen.^^

Sollte quasi ja nur zur Prüfung sein.

Najut, wenn dir erfolgreich geholfen wurde umson ebsser :)

Geschrieben

Achso, nadann^^

Bin jetzt auch wieder an meinem Rechner in der Arbeit und seh grad, dass ich in meinen Programmen mit isLast und isFirst gearbeitet habe.

Nja, auch mal wieder was gelernt. Man lernt nie aus :D

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...