# ResultSet closed



## PhantomXXL (31. Mrz 2005)

```
rs = mysql.QueryAllRecords("SELECT typ_id FROM pnc_rel_makro_funktionstyp WHERE makro_id='"+ makro+"'");

		while( rs.next() ) {
```

Das rs.next im while ruft hierbei den error: 
Debug Interface 3(93): SQLException: Operation not allowed after ResultSet closed
Debug Interface 3(93): SQLState: S1000
Debug Interface 3(93): VendorError: 0

was mich wundert den dazwischen ist genau nur eine leerzeile. denoch wirft er die exception und behauptet auch noch das gerade erst geöffnete ist closed.

die methode QueryAllRecords sieht so aus:


```
public ResultSet QueryAllRecords (String Querystring) {
		ResultSet rs;	
		try {
			rs = stmt.executeQuery(Querystring);
		} catch (SQLException e) {
			rs = null;
		}
		
		return rs;
	}
```

lustigerweise funktioniert die zweite methode QueryOneRecord einwandfrei, nutzt aber nichts da diese wirklich nur einen Eintrag auslesen soll (und kann)


```
public ResultSet QueryOneRecord (String Querystring) {
		ResultSet rs;
		try {
			rs = stmt.executeQuery(Querystring);
			rs.next();
			if( !(rs.isLast() && rs.isFirst() ) ) {
				rs = null;	
			}
		} catch (SQLException e) {
			rs = null;
		}
		
		return rs;				
	}
```


----------



## Bleiglanz (31. Mrz 2005)

du sollst kein Resultset als Rückgabewert einer Methode herumreichen! Vergiss diese Idee!


WO WANN UND WIE soll denn jemals dein stmt geschlossen werden?

Wenn du die Funktion ein zweites mal aufrufst, was ist dann mit stmt? 

usw. usf.


oder die zugehörige connection???


```
} catch (SQLException e) {
         rs = null;
      }
```
WAS IST DENN DAS? Wenn da ein Fehler fliegt dann kriegst du davon nichts mit??? mach irgenwas mit der ex!


----------



## PhantomXXL (31. Mrz 2005)

was auch immer mit stmt is, wenn queryonerecord ruf ich vor dieser while 5 mal auf und es geht... einzig wenn ich ein queryallrecords mach gehts nicht mehr

und die exception is beabsichtigt einfah null, weil sonst wirft es auch wenn ncihts ind er tabelle steht diese, und die verbindungssachen werden e brav abgefangen

ich frag mich eher wieso sagt der immer das resultset ist geschlossen obwohl ich es NICHT schliesse .....


----------



## Bleiglanz (31. Mrz 2005)

ja eben wegen dieser seltsamen Effekte sollst du sowas nicht machen!



> A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
> 
> By default, only one ResultSet object per Statement  object can be open at the same time. Therefore, if the reading of one ResultSet object is interleaved with the reading of another, each must have been generated by different Statement objects. All execution methods in the Statement interface implicitly close a statment's current ResultSet object if an open one exists.



und wenn du dein rs mal rausgegeben hast, dann hast du wenig kontrolle über das stmt

bei einen hast du ja mit next() schon von der DB alles abgeholt, warum der bei der anderen das rs automatisch schliesst ist mir auch nicht klar (scope? lebensdauer?...)

kann dir nur sagen, dass man ein Resultset besser in dem Block lässt, wo es erzeugt wird...


----------



## DP (31. Mrz 2005)

hmm... mal ne frage zu dem rs im block lassen: wo ist denn das problem wenn ich ein rs an eine methode weiterreiche und dort auseinandernehme um die methoden lesbarer zu machen?!

hatte bisher keine probleme...


----------



## PhantomXXL (1. Apr 2005)

naja denke das problem ist mir jetzt klar:
das stmt is ne static, und in der while wird ein neuer aufruf (retrive the next result in a set of results) vond er methode gemacht, sprich ich mach das resultset auf geh in die while, in der while hol ich ein neues resultset, folglich wird das alte geschlossen. was beim nächsten rs.next eben diese exception raushaut


----------



## Bleiglanz (1. Apr 2005)

DP hat gesagt.:
			
		

> hmm... mal ne frage zu dem rs im block lassen: wo ist denn das problem wenn ich ein rs an eine methode weiterreiche und dort auseinandernehme um die methoden lesbarer zu machen?!
> 
> hatte bisher keine probleme...



schau in diesen Thread und du siehtst ein Problem 

Mein Hauptargument: wenn du einem Client erlaubst, mit


```
ResultSet foo = irgeneineHilfMirSache.getErgebnis("SELECT * FROM Tutti");
```

ein ResultSet zu erhalten, dann

* ist der Client gezwungen, foo.close() aufzurufen (das darf er nicht vergessen!)

* gehts in Mutlithreaded Umgebungen sicher irgendwann schief

* ist das ResultSet an eine unsichtbare connection gezwungen, über die man keine Kontrolle hat

Ich hab aber auch SingleThreaded schon komische Sachen erlebt, ich lass das lieber ganz...


Alternative ist das Hollywoodprinzip

schreib dir einen Handler (ein Interface mit einer Methode doSomething(ResultSet rs)) und übergib das


```
public query(String sql, Handler handler){

    ....alles aufmachen

    while(rs.next()){
           handler.doSomething(rs)
     }

    ...alles zumachen


}
```

kann man dann z.B. eine anonyme innere Klasse reinhauen oder sowas


----------



## PhantomXXL (1. Apr 2005)

habs jez umgebaut das man statement und resultset  immer im programm aufmachen muss ausser bei einfachen querys wie insert, delete und update. die wurden sowieso vorher schon immer brav geschlossen.

macht den spass aber halt etwas unübersichtlicher da das query statt einer zeiel vor der verabreitung nu 4 zeilen, je 2 davor und dnach, sind.

und handler kenn ich noch gar nicht *g*


----------

