Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

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

Empfohlene Antworten

Veröffentlicht

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!

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

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

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

} 

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.

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:

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.

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.

Der Vorschlag von TDM hat das Problem gelöst.

Ich musste ein neues Statement aufmachen!

Vielen Dank für eure Hilfe!

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 :)

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

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.