# Liste von ResultSets



## Capasso (7. Mai 2009)

Hi,

sagen wir man hat 40 identisch aufgebaute Tabellen in einer Datenbank.

Jetzt möchte ich aus 15 oder 23 oder ... Tabellen alle Werte auslesen und verabeiten.
Bisher lese ich die Tabellen nacheinander aus und packe die Daten in eine ArrayList und  bearbeite anschließend die, doch sehr große, Liste.

Jetzt habe ich mir gedacht, dass es wahrscheinlich besser wäre die Daten direkt zu verarbeiten anstatt sie erst komplett in die ArrayList zu laden.

Am Besten wäre es wenn ich ne Klasse hätte die beliebieg viele ResultSets aufnehmen kann, dann nacheinander über diese iteriert und mir ein bestimmtes Attribut zurückgibt.

Hab mir schon auf java-blog-buch.de die Themen Iterator und Collections durchgelesen, weiß aber nicht genau wie ich anfangen soll.

Hat jemand einen oder mehr Tipps


----------



## SlaterB (7. Mai 2009)

Liste von ResultSets: List<ResultSet>
ResultSets einfügen: add, entnehmen: get,
einzelne ResultSets durchlaufen,

das sind doch alles bekannte einfache Schritte, du musst sie nur programmieren..,

noch schlauer wäre vielleicht, wenn überhaupt, nur die Queries zu sammeln 
und dann nacheinander die Queries zustellen und die Ergebnisse zu verarbeiten,
ohne mehrere ResultSets vorrätig zu haben, immer eins reicht, wenn fertig, dann nächste Query stellen


----------



## Ebenius (7. Mai 2009)

SlaterB hat gesagt.:


> Liste von ResultSets: List<ResultSet>


Alternativ kann man auch die Datenbank die Arbeit machen lassen und alles in einem SELECT abhandeln und nur ein Resultset benutzen. Dazu könnte man eine View auf der Datenbank benutzen oder ein großes SELECT-Statement, ad lib.

Für Oracle könnte die View so aussehen: 
	
	
	
	





```
CREATE OR REPLACE VIEW v_joined_tables AS
	SELECT	'Table 1' AS table_name,
		*
	FROM tbl_table_1
	UNION ALL
	SELECT	'Table 2' AS table_name,
		*
	FROM tbl_table_2
	UNION ALL
	...
;
```
Die Query dazu könnte dann lauten: 
	
	
	
	





```
SELECT * FROM v_joined_tables WHERE table_name IN ('Table 15', 'Table 23')
```

Die Super-Query wäre entsprechend: 
	
	
	
	





```
SELECT	'Table 15' AS table_name,
	*
FROM tbl_table_15
UNION ALL
SELECT	'Table 23' AS table_name,
	*
FROM tbl_table_23
```
Ebenius


----------



## tfa (7. Mai 2009)

Erstmal würd ich mich fragen, warum es 40 identisch aufgebaute Tabellen gibt.


----------



## Capasso (7. Mai 2009)

Ebenius hat gesagt.:


> Die Super-Query wäre entsprechend:
> 
> 
> 
> ...



Das hab ich schonmal ausprobiert, aber dann dauerte die SQL Abfrage ziemlich lange, viel länger als alles einzeln zu machen.



tfa hat gesagt.:


> Erstmal würd ich mich fragen, warum es 40 identisch aufgebaute Tabellen gibt.



Weil jede Tabelle unterschiedliche Informationen speichert. Sie haben nur die gleiche Struktur.



SlaterB hat gesagt.:


> Liste von ResultSets: List<ResultSet>
> ResultSets einfügen: add, entnehmen: get,
> einzelne ResultSets durchlaufen,
> 
> ...



Hab ich mir auch schon gedacht.

Aber ich hätte gerne den Sql und Datenbankkram nicht in der selben Klasse.

Wie soll ich das Erklären.

Datanbankklasse erstellt eine Liste von ResultSets (Klasse: ResultSetList oder so) und die Bearbeitungklasse kann dann ganz einfach mit einer Foreach-schlreife über alle Ergebnisse aller ResultSet iterieren.


----------



## maki (7. Mai 2009)

> Weil jede Tabelle unterschiedliche Informationen speichert. Sie haben nur die gleiche Struktur.


Ähm.. das ist bestenfalls suboptimal für ein DB Schema.

ResultSets sollten so schnell wie möglich geschlossen werden, denn jedes offene ResultSet belegt DB Server Ressourcen.



> ber ich hätte gerne den Sql und Datenbankkram nicht in der selben Klasse.


ResultSets gehören aber nunmal zum "Datenbankkram"


----------



## SlaterB (7. Mai 2009)

> Aber ich hätte gerne den Sql und Datenbankkram nicht in der selben Klasse.

wenn du die ResultSets übergibst, dann hast du ja auch SQL-Kram in derselben Klasse,

du kannst aber gerne WrapperObjekte bauen

```
List<QueryVorbereitung> list =..;
for (QueryVorbereitung q : list) {
   ResultSet r = q.gibDeinResultSetObGespeichertOderNeuAusgeführtMirEgal();
   r durchlaufen usw.
   q.binFertigFallsDuIrgendwasClosenMusstDannJetztMirEgal();
}
```
eine Liste der ResultSets geht natürlich immer noch


----------



## Capasso (7. Mai 2009)

maki hat gesagt.:


> Ähm.. das ist bestenfalls suboptimal für ein DB Schema.
> 
> ResultSets sollten so schnell wie möglich geschlossen werden, denn jedes offene ResultSet belegt DB Server Ressourcen.
> 
> ...



Da hab ich mich falsch ausgedrückt. Ich meinte ich hätte gerne nichts von beidem in der Bearbeitungklasse


----------



## tfa (7. Mai 2009)

> Weil jede Tabelle unterschiedliche Informationen speichert. Sie haben nur die gleiche Struktur.


Wie wär's, wenn du nur eine Tabelle hast und der eine zusätzliche Spalte gibst, wo du den Typ der Information reinschreibst? Dann hast du nicht 40 Tabellen, sondern nur eine mit einer Diskriminator-Spalte, die 40 unterschiedliche Werte haben kann.


----------



## Capasso (7. Mai 2009)

tfa hat gesagt.:


> Wie wär's, wenn du nur eine Tabelle hast und der eine zusätzliche Spalte gibst, wo du den Typ der Information reinschreibst? Dann hast du nicht 40 Tabellen, sondern nur eine mit einer Diskriminator-Spalte, die 40 unterschiedliche Werte haben kann.



Nein, die Tabellen müssen so bleiben wie sie sind.


----------



## maki (7. Mai 2009)

Würde mir da eine/mehrere Datenstruktur schreiben, welche die Werte aus den ResultSets aufnimmt.
Dann die Abfragen abfeuern, und jedes einzelne ResultSet in diese Datenstruktur(en) umwandeln.
Wenn dann alle Daten aus der DB gelesen sind, kannst du ja mit der Verarbeitung beginnen.


----------



## ARadauer (7. Mai 2009)

nebenbei... aufpassen das das Statement und die Connection nicht geschlossen wird, bevor du mit der Verarbeitung fertig bist, sonst wird dein Resultset auch geschlossen...


----------



## Ebenius (7. Mai 2009)

maki hat gesagt.:


> Capasso hat gesagt.:
> 
> 
> > Weil jede Tabelle unterschiedliche Informationen speichert. Sie haben nur die gleiche Struktur.
> ...


Die Aussage ist ziemlich pauschal und damit auch oft falsch. 



maki hat gesagt.:


> ResultSets sollten so schnell wie möglich geschlossen werden, denn jedes offene ResultSet belegt DB Server Ressourcen.


Stimmt oft. Ist aber letztlich immer abhängig vom Anwendungsfall. Es gibt nicht wenige Fälle in denen die direkte Verarbeitung der Datensätze mehr Sinn ergibt, als die Daten alle in eine interne Struktur abzulegen und danach zu verarbeiten.



maki hat gesagt.:


> Würde mir da eine/mehrere Datenstruktur schreiben, welche die Werte aus den ResultSets aufnimmt. [...] Wenn dann alle Daten aus der DB gelesen sind, kannst du ja mit der Verarbeitung beginnen.


Bei einer Million Einträge überlegt man sich das dann doch anders. 



Capasso hat gesagt.:


> Das hab ich schonmal ausprobiert, aber dann dauerte die SQL Abfrage ziemlich lange, viel länger als alles einzeln zu machen.


Hier können je nach Datenbanksystem PreparedStatements helfen. Oder Du probierst es mal mit der View; das kann je nach Datenbanksystem ebenfalls helfen.

Wenn es Dir nur um die Trennung geht, dann kapsele doch einfach Deine Datenbankzugriffe wie von Slater bereits erwähnt.

Ebenius


----------



## pada (1. Jan 2011)

Hallo zusammen!

Ich wünsche allen ein gutes neues Jahr!

Ich greife diesen Thread nochmal auf da ich ein ähnliches Problem habe.

Ich muß mit meiner Gruppe eine Zwischenschicht programmieren um eine horizontal verteilte Datenbank zu realisieren.
Das ist ein stark vereinfachtes System und soll nicht den vollen Funktionsumfang von SQL-Anweisungen abbilden. Es sollen "einfache" Queries aller SELECT * FROM XY ODER BY Z aber auch etwas komplexere wie einige JOINs möglich sein.

Technische Infrastruktur:
3 Oracle Server (physikalisch getrennte Maschinen S1-S3)

Hintergrund:
Der Inhalt einer Tabelle wird auf alle drei Server verteilt gespeichert. Bedeutet Row1-20 auf S1, Row21-20000 auf S2, Row20001-30000 auf S3, Row30001-32000 auf S2, usw.
Die Struktur (CREATE) der Tabelle ist auf allen Servern identisch, Contraints werden soweit nötig (z.B. ForeignKey) werden außerhalb der Oracle Instanzen geprüft, da evtl. eine Referenz auf einem anderen Server gespeichert ist.

Soweit mir bekannt gibt es keine Möglichkeit "einfache" (ohne zusätzliche Ebenen) Oracle Server zu überreden sich mit den anderen Servern auszutauschen.

Ein einfaches SELECT * FROM XY erzeugt bei mir ein PseudoResultSet das die ähnliche Arbeitsweise beim auslesen durch den Anwender hat wie Salter B mit der Wrapperklasse beschreibt. Ich führe auf allen drei Servern das SELECT aus und bekomme drei ResultSets welche ggf. sortiert sind und gehe iteriere strukturiert über diese so das der Anwender nichts bemerkt.

ABER wenn ich jetzt die JOINs noch machen will, also zwei Tabellen (jetzt 2 verschiedene ResultSets) joinen, dann kann ich wohl wie ich gesehen habe die Klasse JoinRowSet nutzen, aber dafür benötige ich je ein ResultSet für jede Tabelle wenn ich es richtig verstanden habe.

Und da ist das große Problem:
Jetzt muß ich aus den 2x3 ResultSets (3 weil eines von jedem Server um eine gesamte Tabelle darzustellen) 2x1 ResultSets machen. 
Muß sozusagen gesamtSet=Set1.append(Set2.append(Set3))) durchführen.
Habe aber keine Methoden gefunden und auch keine Klassen gefunden die eine Row in dem Set darstellen oder wie ich eine ganze Zeile als Struktur auslesen kann um diese dann ggf. in eine riesige ArrayList o.ä. zu packen. Ich wollte eigentlich nach Möglichkeit gerne die ResultSet Klassen weiter nutzen da scheinbar die Verbindung zur physikalischen DB weiter besteht und die Daten erst tatsächlich bei Bedarf gelesen werden, das ResultSet scheinbar "nur" eine Struktur des Ergebnisses darstellt. Damit könnte ich Speicher sparen oder gar bei xMillionen Sätzen ein OutOfMemory verhindern.

Hat jemand eine Idee wie ich n-ResultSets zu einem zusammen fassen kann? Die Struktur aller Sets ist identisch das alle die gleiche Tabellen (Struktur) abfragen, halt nur auf n-Servern.
Oder gibt es Frameworks die man nutzen könnte.

Vielen Dank!

Grüße

PS: Hab so viel geschrieben damit es möglichst deutlich wird.


----------



## pada (5. Jan 2011)

Habe den Beitrag im Bereich Datenbank-Programmierung angelegt, weil er dort besser hin passt.

http://www.java-forum.org/datenbankprogrammierung/111482-verteilte-datenbank-programmieren.html


----------

