SQL_Abfrage-Ergebnis (ResultSet) in String[] speichern

it-girl

Aktives Mitglied
Hallo,

ich möchte das Ergebnis einer SELECT-Anfrage an meine DB2, also das ResultSet, in einem Array speichern. Für jede Zeile ein "Array-Kästchen". Da ich nur eine Spalte selektiere, dürfte das doch eigentlich kein Problem sein.
Bis jetzt habe ich das mit ResultSet.getString(1) in einer while-Schleife ausgelesen und versuche es, in dem Array zu speichern.

Java:
DataBase db = new DataBase();
ResultSet dt = null;
String[] combo1Items = new String[db.dataCounter];
int i;
db.getDB("SELECT SCOPE FROM TABLE GROUP BY SCOPE HAVING Count(SCOPE)>=1", dt);
GUI.combo1 = new JComboBox();
if (db.dataCounter > 0) {
	combo1Items = new String[db.dataCounter - 1];
	try {
		i = 0;
		while (dt.next()) { //NullPointerException verweist hier drauf
			System.out.println(dt.getString(1));
			combo1Items[i] = dt.getString(1);
			i++;
		}
	} catch (SQLException e) {
		e.printStackTrace();
	}

db.dataCounter zählt die Zeilen des ResultSets. Wenn ich diese Zahl ausgebe, ist das sogar > 0, aber trotzdem bekomme ich immer eine NullPointerException, wenn es an die Schliefe geht. Was mache ich falsch??

Ich hoffe, ihr könnt mir helfen. Danke schon mal für eure Antworten.

LG it-girl
 
ResultSet bietet u.a. die 2 Methoden hasNext() und next()
hasNext ist gut für die Bedingung einer Schleife geeignet, next() gar nicht 😉
 
hasNext ist gut für die Bedingung einer Schleife geeignet, next() gar nicht 😉

Aber immer, wenn ich Internet was in der Richtung gesucht habe, stand in der while-Schleife next() und das hat bei mir sonst auch immer funktioniert. Warum dann hier nicht?
Und was genau ist der Unterschied zwischen hasNext() und next()?
 
Dein ResultSet ist vielleciht null?

Das habe ich auch schon überlegt, sieht eigentlich auch fast so aus, da am Anfang ja ResultSet dt = null; steht. Aber dt wird dann an die Methode getDB(String query, ResultSet dt) übergeben, dort mit dem Ergebnis von query gefüllt und die Zeilen gezählt und wenn ich die Zeilenanzahl dann ausgebe, zeigt es mir ja auch einen Wert größer 0, also muss ja was drin sein. Ich kann den Inhalt auch ausgeben, wenn ich ein System.out.println(dt.getString(1); in die Schleife rein schreibe, wo die Zeilen gezählt werden. Komisch ist, wenn ich das gleiche in der geposteten Schleife mache, bringt er mir eben diese NullPointerException, ich kann es also auch nicht im Array speichern.
 
Java:
public static ResultSet getDB(String query, ResultSet rs) {
		dataCounter = 0;
		try {
			connectToDB(); //stellt die Verbindung zur DB2 her
			Statement pstmt = conn.createStatement();
			rs = pstmt.executeQuery(query);
			while (rs.next()) {
				dataCounter ++;
				System.out.println(rs.getString(1));
			}
			System.out.println(dataCounter);
			conn.commit();
			pstmt.close();
			rs.close();
			conn.close();
		} catch (SQLException e) {
			e.getMessage();
		}
		return rs;
	}

Bei CallByValue wird eine Kopie der Variablen an die Methode übergeben und bei CallByReference das Objekt selber, bzw eine Referenz auf das Original-Objekt... Wie hängt das jetzt hiermit zusammen?
 
Bei CallByValue wird eine Kopie der Variablen an die Methode übergeben und bei CallByReference das Objekt selber, bzw eine Referenz auf das Original-Objekt... Wie hängt das jetzt hiermit zusammen?
Java unterstützt nur CallByValue, sonst nix 🙂
Jetzt sollte dir auch klar sein, dass es Quatsch ist, das ResultSet als Parameter zu übergeben.

Sinn macht es nur als Rückgabewert:
Java:
dt = db.getDB("SELECT SCOPE FROM TABLE GROUP BY SCOPE HAVING Count(SCOPE)>=1");
Musst deine Methode natürlich noch anpasen.
 
Java unterstützt nur CallByValue, sonst nix 🙂
Jetzt sollte dir auch klar sein, dass es Quatsch ist, das ResultSet als Parameter zu übergeben.
Ja ok, das ist mir dann klar. Aber warum geht das nicht? Kann ich dann nur Strings und ints und booleans und so einfache Sachen übergeben?

Aber was mir dann trotzdem noch nicht klar ist: Warum zählt der dataCounter dann Datenzeilen im ResultSet?? Zählt das "ResultSet rs" im Methodenkopf schon als Deklaration?
 
Ja ok, das ist mir dann klar. Aber warum geht das nicht? Kann ich dann nur Strings und ints und booleans und so einfache Sachen übergeben?
Kannst alles übergeben, aber eben nur nach den Regeln des CallByValue.

Aber was mir dann trotzdem noch nicht klar ist: Warum zählt der dataCounter dann Datenzeilen im ResultSet?? Zählt das "ResultSet rs" im Methodenkopf schon als Deklaration?
Natürlich.
 
Ok, das hab ich nun geändert. Aber nun bekomme ich eine SQLException:
com.ibm.db2.jcc.b.SqlException: [ibm][db2][jcc][10120][10898] Ungültige Operation: result set ist geschlossen.
Kann ich jetzt nicht mehr auf das ResultSet zugreifen, weil ich es schon in der Methode getDB() geschlossen habe? Ich habe es doch als return-Wert wieder zurückgegeben... *verwirrt bin*
 
Wenn du die Connection schliesst, schliesst sich auch automatisch das ResultSet und das Statement, steht alles in der Doku.
 
Ja das schon, aber ich schließe es ja erst, nachdem ich es nicht mehr brauche. Das müsste doch eigentlich funktionieren oder?

Java:
DataBase db = new DataBase();
ResultSet dt = null;
String[] combo1Items = new String[db.dataCounter];
int i;
dt = db.getDB("SELECT SCOPE FROM TABLE GROUP BY SCOPE HAVING Count(SCOPE)>=1");
GUI.combo1 = new JComboBox();
if (db.dataCounter > 0) {
    combo1Items = new String[db.dataCounter - 1];
    try {
        i = 0;
        while (dt.next()) {
            System.out.println(dt.getString(1));
            combo1Items[i] = dt.getString(1); //hier brauch ich es ja noch, aber nach der Schleife ja nicht mehr
            i++;
        }
        dt.close(); //also kann ich es doch dann hier wieder zu machen oder?
    } catch (SQLException e) {
        e.printStackTrace();
    }
 
Java unterstützt nur CallByValue, sonst nix 🙂
Jetzt sollte dir auch klar sein, dass es Quatsch ist, das ResultSet als Parameter zu übergeben.
Ich hab grad gesehen, dass ich in einer anderen Methode
Code:
printResultSet(ResultSet rs)
auch ein ResultSet als Übergabeparameter benutzt habe. Und diese Methode funktioniert einwandfrei. Also muss es ja doch CallByReference in Java geben oder es muss zumindest das mit dem ResultSet als Parameter gehen... Tut mir Leid, dass ich deine Aussage da widerlegen muss...
 
Offensichtlich hast du CallByreference vs. CallByValule doch nicht verstanden.
Aber anstatt dein fehlendes Wissen nachzuholen oder gar nachzufragen, stellst du dich hin und gibst einfach mal Blödsinn wie "Java hat doch CallByReference blablabla" von dir.

Nochmals: Wenn du die Connection schliesst, wird auch das Statement und das ResultSet geschlossen.

An CallByValue in Java kann man nicht rütteln, ist so definiert und umgesetzt.
Was nicht stimmt ist wohl eher dein Verständnis 😉

Warum sich als Anfänger eigentlich gleich mit so komplexen Themen wie DB auseinandersetzen?
Wäre es nicht sinnvoller vorher die Grundregeln zu lernen & verstehen?
 
Also das mit der NullPointer hab ich nun erst mal anders umgangen.
Jetzt würde ich dann aber doch ganz gerne wissen, wie ich das ResultSet wie oben beschrieben in ein Array speichern kann? Geht das überhaupt?

Habe das bis jetzt so gemacht:
Java:
String[] combo1Items = new String[db.dataCounter];
while (dt.next()) {
	db.dataCounter++;
	System.out.println(dt.getString(1)); //das funktioniert
	combo1Items[i] = dt.getString(1); //aber das nicht
	i++;
}
Da bekomme ich nach 2 Schleifendurchgängen eine ArrayIndexOutOfBoundsException.
 
Offensichtlich hast du CallByreference vs. CallByValule doch nicht verstanden.
Aber anstatt dein fehlendes Wissen nachzuholen oder gar nachzufragen, stellst du dich hin und gibst einfach mal Blödsinn wie "Java hat doch CallByReference blablabla" von dir.

Warum sich als Anfänger eigentlich gleich mit so komplexen Themen wie DB auseinandersetzen?
Wäre es nicht sinnvoller vorher die Grundregeln zu lernen & verstehen?
Wenn ich dir aber sage, als wir das in der FH so gemacht haben (ja, sogar so gelernt haben), hat es funktioniert. Und in meinem jetzigen Programm habe ich das in dieser printResultSet-Methode wieder genauso gemacht und es hat ebenfalls funktioniert. Vielleicht habe ich mich vorher etwas überheblich ausgedrückt, tut mir Leid. Aber irgendwie stimmt doch da was nicht, wenn du sagst, es geht nicht und bei mir geht es aber doch 😉 ...sehr merkwürdig...

Und wer sagt, dass ich Anfänger bin? Ich denke, jeder hat mal einen Tag, wo er mal so richtig auf dem Schlauch steht. Heute war meiner 😀

LG it-girl
 
Also das mit der NullPointer hab ich nun erst mal anders umgangen.
Jetzt würde ich dann aber doch ganz gerne wissen, wie ich das ResultSet wie oben beschrieben in ein Array speichern kann? Geht das überhaupt?

Habe das bis jetzt so gemacht:
Java:
String[] combo1Items = new String[db.dataCounter];
while (dt.next()) {
	db.dataCounter++;
	System.out.println(dt.getString(1)); //das funktioniert
	combo1Items[i] = dt.getString(1); //aber das nicht
	i++;
}
Da bekomme ich nach 2 Schleifendurchgängen eine ArrayIndexOutOfBoundsException.

Erm... Was tust du da? Du initialisierst einmalig den String[]. Wenn der db.dataCounter am Anfang 1 ist dann hast du einen Array mit genau einer Stelle. Wenn du dann bei der 2 bist rappelt es natürlich 😉

Wenn du die Anzahl der Spalten nicht weiß nimm eine List<String>, zum Beispiel eine ArrayList<String> und keinen Array. Arrays in Java kann man nicht vergrößern/verkleinern.
 
Wenn ich dir aber sage, als wir das in der FH so gemacht haben (ja, sogar so gelernt haben), hat es funktioniert. Und in meinem jetzigen Programm habe ich das in dieser printResultSet-Methode wieder genauso gemacht und es hat ebenfalls funktioniert. Vielleicht habe ich mich vorher etwas überheblich ausgedrückt, tut mir Leid. Aber irgendwie stimmt doch da was nicht, wenn du sagst, es geht nicht und bei mir geht es aber doch ...sehr merkwürdig...
Dann sage ich dir, das du nichtmal genau weisst was du da machst, und nichtmal in der Lage bist zu verstehen, was ich gesagt habe und was geht und was nicht.

Und wer sagt, dass ich Anfänger bin? Ich denke, jeder hat mal einen Tag, wo er mal so richtig auf dem Schlauch steht. Heute war meiner
Du stellst Anfängerfragen, stellst Grundlagen in Frage die so gegeben sind und schaffst es nichtmal, eine Methode zu schreiben die funktioniert -> Anfängerin 😀
 
Und in meinem jetzigen Programm habe ich das in dieser printResultSet-Methode wieder genauso gemacht und es hat ebenfalls funktioniert. Vielleicht habe ich mich vorher etwas überheblich ausgedrückt, tut mir Leid. Aber irgendwie stimmt doch da was nicht, wenn du sagst, es geht nicht und bei mir geht es aber doch 😉 ...sehr merkwürdig...

Nebenbei: ResultSets sollte man nicht unbedingt quer durchs Programm "schleppen". Sobald du die Connection oder das Statement schließt oder anderweitig weiternutzt sind die weg.

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.

Idealerweise machst du sowas:

Java:
private List<MyRow> getQueryResult{
    // hier query ausführen und das Ergebiss in eine eigene Datenstruktur "kopieren"
}

private printQueryResult(List<MyRowY rows>{
   // dein Datenstruktur "drucken"
}
 
Erm... Was tust du da? Du initialisierst einmalig den String[]. Wenn der db.dataCounter am Anfang 1 ist dann hast du einen Array mit genau einer Stelle. Wenn du dann bei der 2 bist rappelt es natürlich 😉
Ja ok, stimmt, klingt logisch. Ich brüte halt schon seit 2 Tagen darüber und irgendwann sieht man seine eigenen Fehler nicht mehr :autsch: Danke 🙂

Arrays in Java kann man nicht vergrößern/verkleinern.
Das weiß ich 🙂 Hab den Fehler nur wie gesagt nicht entdeckt... 😳

Du stellst Anfängerfragen, stellst Grundlagen in Frage die so gegeben sind und schaffst es nichtmal, eine Methode zu schreiben die funktioniert -> Anfängerin
Sagen wir so: Ich war mal Fortgeschritten bis eigentlich ziemlich gut, aber dann habe ich ein Jahr lang nicht mehr programmiert (frag nicht warum) und muss da jetzt wieder rein kommen 🙂 Aber es läuft eigentlich schon ganz gut (mit ein paar Ausnahme😳)
Und das mit den gegebenen Grundlagen, ich glaube dir ja, dass man ResultSets nicht übergeben kann. Trotzdem wundere ich mich dann, dass das bei mir geklappt hat... aber egal 🙂
Und nur weil diese Methode nicht funktioniert, heißt das nicht, dass ich gar keine schreiben kann, die funktionieren.

LG it-girl
 
Und das mit den gegebenen Grundlagen, ich glaube dir ja, dass man ResultSets nicht übergeben kann. Trotzdem wundere ich mich dann, dass das bei mir geklappt hat... aber egal

Selbstverständlich kann man Variablen vom Typ ResultSet als Parameter an Methoden übergeben. Aber eben nur per "Call by Value" und nicht per "Call by Reference". Da es sich bei ResultSets um Objekte handelt wird bei der Übergabe die Referenz kopiert. D.h. wenn man die Referenz innerhalb der Methode auf ein anderes Objekt zeigen lässt, dann ist diese Änderung außerhalb der Methode nicht sichtbar (Referenz wurde ja kopiert). Eine Änderung des inneren Zustands des Objekts ist aber sehr wohl nach außen sichtbar. Wenn Java "Call by Reference" unterstützen würde, dann wäre es möglich die Referenz umzubiegen so dass die Änderung außerhalb sichtbar ist.
 
Idealerweise machst du sowas:

Java:
private List<MyRow> getQueryResult{
    // hier query ausführen und das Ergebiss in eine eigene Datenstruktur "kopieren"
}

private printQueryResult(List<MyRowY rows>{
   // dein Datenstruktur "drucken"
}

Danke, das hat mir sehr geholfen. Damit geht es jetzt :toll:

LG it-girl
 
also ich hatte das gleiche problem ich hab das mit einer List + Iterator gelöst das ResultSet bzw was du auch verwendest, jeden Datensatz mit einer while schleife eingelesen und den Iterator dieser List dann jeden Datensatz einzeln auslesen lassen und via SysO ausgegeben

so in etwa:

Java:
while(it.hasNext())
						{
							String strgSQL = (String) it.next();
							System.out.println(strgSQL);
							PreparedStatement selectPrepSt = con.prepareStatement(strgSQL);
							boolean result = selectPrepSt.execute();
							System.out.println("result = " + result + "Import Tabelle gefüllt!" );
						}

lg
 

Zurück
Oben