Laden...

Ganze Tabelle in mehreren kleinen Päckchen auslesen

Erstellt von chanderegg vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.050 Views
C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 13 Jahren
Ganze Tabelle in mehreren kleinen Päckchen auslesen

verwendetes Datenbanksystem: Oracle 9

Hallo zusammen

Ich muss Daten von einem Oracle Server auf einen SQL Server exportieren. Leider kann ich das nicht mit dem Tool das im SQL Server zur Verfügung steht, da ich kein Oracle Client installieren darf.
Nun schreibe ich ein Programm. Ich benutze dafür SQL Bulk. Das funktioniert super und ist sehr schnell. Leider muss ich dazu die Daten vom Oracle Server in ein DataSet laden. Bei einer Tabellengrösse von über 5 Mio. Einträgen bekomme ich da eine OutOfMemoryException.
Deshalb mache ich zuerst einen Count und schaue, wieviele Reihen in der Tabelle vorhanden sind.
Wenn über 100'000 Tausend Einträge vorhanden sind, möchte ich diese nacheinander auslesen. Das heisst, zuerst die ersten 100'000 dann die zweiten etc.
Leider funktioniert das nicht. Ich habe versucht die Bedingung mit rownum zu machen (geht für die ersten aber dann nicht mehr) oder mit rowid (entspricht nicht einer Zahl sondern einem generierten String).

Kann mir jemand einen Tipp geben, wie ich mein Problem lösen kann? Konnte bis jetz nur herausfinden, dass meine Lösungsansätze nicht funktionieren

Vielen Dank für eure Hilfe
chanderegg

W
955 Beiträge seit 2010
vor 13 Jahren

Hi,

ROWNUM in oracle wird als letzter Schritt nach (einer möglichen) Sortierung der Ergebnismenge beigefügt. Die erste Zeile bekommt die 1, der Zähler erhöht sich dabei um eins. Wenn Du jetzt solche Abfragen wie WHERE ROWNUM > 10 verwendest wird niemals eine Zeile im Ergebnis auftauchen, da keine Zeile gefunden wird welche den Zähler von 1 auf 2 usw. hochzählt. Die Lösung besteht darin mit einer dynamic view zu arbeiten (ungetestet, weiß nicht mehr ob ROWNUM ein alias braucht):


SELECT * FROM
(SELECT *,ROWNUM FROM table) v
WHERE v.ROWNUM BETWEEN 10 AND 20

Dieser Weg ist jedoch ungünstig, was ist wenn jemand anders Daten modifiziert? Willst Du alles mit Repeatable Read machen wenn es überhaupt hilft? Vllt ist es einfacher über den Primärschlüssel zu gehen, wenn es ein Integer ist.

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 13 Jahren

Wie meinst du, wenn jemand anderes Daten modifiziert? ich will ja nur den Export machen. In dieser Zeit darf niemand die Daten verändern und nachher arbeiten sie mit dem SQL Server.
Das mit dem Primärschlüssel geht leider auch nicht. Ich muss mehrere Tabellen exportieren und habe überall unterschiedliche Primärschlüssel.

Dein Query funktioniert, wenn man das * aus dem 2. Select entfernt. Habe ein ähnliches bereits im Netz gefunden. Leider kann ich das * nicht integrieren. Werde es noch ein bisschen versuchen.


SELECT * FROM
(SELECT ROWNUM AS a FROM le001 ORDER BY rownum) v
WHERE v.a BETWEEN 10 AND 20

so funktionierts und gibt die Rownum zurück. Ich müsste aber die Werte dieser Reihen haben.


SELECT * FROM
(SELECT ROWNUM AS a, * FROM le001 ORDER BY rownum) v
WHERE v.a BETWEEN 10 AND 20

Hier gibts den Fehler ORA-00936: Ausdruck fehlt

Vielen Dank für den Tipp. Ich hoffe, dass ich dies noch zum Funktionieren bringe

F
10.010 Beiträge seit 2004
vor 13 Jahren

Schonmal das SyncFramework von MS angeschaut?
Da ist sowas nicht nötig.

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 13 Jahren

Bin noch einmal einen Schritt weiter gekommen. Ich habe nun folgendes Query


SELECT * FROM
(SELECT ROWNUM rnum, a.* FROM
(SELECT * FROM le001) a WHERE ROWNUM < 20)
WHERE rnum > 10

Dies gibt mir alle Daten, die ich benötige. Doch leider ist dies immer noch nicht das, was ich will, denn die Rownum wird nun auch ausgegeben und ich möchte diese nicht, da das SQL BULK dies nicht versteht (resp. nicht braucht).

vom SyncFramework habe ich noch nichts gehört. werde ich gleich mal anschauen.

Danke