Autor Beitrag
deefens
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Do 23.09.04 22:31 
Hallo Forumsteilnehmer,

ich brauche für meine Client-Anwendung eine Funktion, die das
Exportieren von Tabellendaten im CSV-Format ermöglicht. Da ein Select
* auf eine sehr große Tabelle dazu führt, dass der Client erstmal
längere Zeit gar nichts macht, wollte ich die Daten in mehreren
Durchläufen abwechselnd auslesen und auf die Platte schreiben.

Ich habe mich Serverseitig bereits schlau gemacht und mir folgenden
Code zurechtgebastelt:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
spool c:\test
declare
  cursor c1 is
    select * from F_VBO_DC_OVERVIEW;
  type t_records is table of F_VBO_DC_OVERVIEW%ROWTYPE;
  records t_records; 
begin
  open c1;
  loop
    fetch c1 BULK COLLECT INTO records LIMIT 5;
    for i in 1..records.count loop
      dbms_output.put_line(records(i).MARKET_SHARE_PYM);
    end loop;
    exit when c1%notfound;
  end loop;
  close c1;
end;
/
spool off


Statt einem Spool in eine Datei will ich aber die Daten zur
Clientanwendung übertragen und dort sequentiell weiterverarbeiten vor
dem Speichern. HAt jemand eine Idee, wie ich das anstellen könnte? Ich
bräuchte sozusagen eine konstante Verbindung zur Datenbank während des
Fetchvorgangs mit Übertragung der Zwischenergebnisse... Als
DAtenbankkomponenten verwende ich die ODAC-Komponente von CoreLab, es
täte aber auch eine Lösung für dbExpress.

Danke für jeden Hinweis!!
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Fr 24.09.04 09:20 
Hallo,

Oracle ist nun nicht mein Fachgebiet, aber unter Interbase gibt es die Möglichkeit, nur Teildaten zu holen:

ausblenden Quelltext
1:
select first 100 skip 100 * from Tabelle					

würde die ersten 100 Datensätze überspringen und die nächsten 100 liefern.

Gibt es vielleicht einen Primärschlüssel, an dem man sich halten könnte? Wenn das z.B. ein Integerfeld wäre, könntest du so vorgehen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
begin
  //Den höchsten vorhandenen Primärschlüsselwert der Tabelle ermitteln
  Dataset.Active:=False;
  Dataset.SQL.Text:='select Max(PrimaryKey) from Tabelle';
  Dataset.Active:=true;
  HighestPrimaryKey:=Dataset.FieldByName('PrimaryKey').AsInteger;

  //Daten holen
  MaxPrimaryKeyFound:=0;
  Repeat
    Dataset.Active:=False;
    Dataset.SQL.Text:='select * from Tabelle where PrimaryKey>'+IntToStr(MaxPrimaryKeyFound)+' and PrimaryKey<'+IntToStr(MaxPrimaryKeyFound+1000)+' order by PrimaryKey';
    Dataset.Active:=True;
    //Den höchsten Primärschlüsselwert im Dataset suchen
    MaxPrimaryKey:=FindMaxPrimaryKeyInDataset;
    //Dataset-Daten speichern
    SaveDatasetToDisk;
  until MaxPrimaryKey=HighestPrimaryKey;
end;


Cu,
Udontknow
deefens Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Fr 24.09.04 10:15 
Titel: Danke für die Antwort
leider hilft mir deine antwort nicht weiter, da es ein skip-ähnliches statement in oracle nicht gibt. in mysql würde ich einfach die limit-klausel verwenden, aber unter oracle sind selbst solch "billigen" features nicht auszumachen. ich kann mich auch nicht am primärschlüssel orientieren, da ich mich in meinen proggy nicht darauf verlassen kann, dass die jeweilige quelltabelle einen pk definiert hat :( ich hab auch schon überlegt, was mit der rowid anzufangen, aber die ist leider nicht numerisch sondern enthält ausschliesslich buchstaben...

ich bin echt langsam am verzeifeln
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Fr 24.09.04 10:20 
Zitat:
ich hab auch schon überlegt, was mit der rowid anzufangen, aber die ist leider nicht numerisch sondern enthält ausschliesslich buchstaben...
Auch Strings kann man miteinander vergleichen. Wenn das also eine Art Primärschlüssel ist, na gut, dann eben ein String als Primärschlüssel benutzen.

Cu,
Udontknow
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Fr 24.09.04 11:27 
Es gibt eventuell folgende Möglichkeit bei Oracle:
ausblenden Quelltext
1:
2:
select * from artikeldaten
where rownum < 100

Was dabei allerdings nicht geht ist folgendes:
ausblenden Quelltext
1:
2:
select * from artikeldaten
where rownum > 100

Wenn du also den 2ten Block holen willst, gibt es keine einfache Lösung. Ich würde dann evtl mit einem "not in" (in einem Sub-Select) über die RowId arbeiten. Ist allerdings bei sehr großen Datenmenge ziemlich langsam, fürchte ich. Aber vielleicht hilft das als Ansatz.