Hallo Uwe,
ich verwende die MARS Komponenten von Andre Magni und stelle damit einen REST-
API Server bereit. Ich habe also keine Control die an der
Query gebunden sind.
Um alle Personen abzurufen, nutze ich die Methode etwa so:
Delphi-Quellcode:
function TApiResource.GetPersonen: TFDQuery;
begin
result :=FD.Query(' SELECT * FROM PERSONEN ');
end;
als Result bekommen ich:
Code:
{"RecordSet" : [
{
"PERSONID" : 295,
"NAMEN" : "Brandl",
"TITEL" : null,
"VORNAME" : "Carmen",
"GEBURTSDATUM" : "29.08.1994",
"PERSONALNR" : "10115854",
"EINTRITTJAHR" : 0,
"FACHNR" : 101006,
"FACH" : "SV45HD",
},
...
Die Datenmenge ist relativ groß mit ca. 500.000 Records und es werden viel mehr Felder ausgegeben als hier im Beispiel.
Die Datenmenge kann ich übrigens nicht auf einmal exportieren da der Speicher nicht ausreicht. Die Feldbezeichner machen den größten Anteil aus und die wiederholen sich bei jedem Record.
Jetzt dache ich, ich durchlaufe die
Query und exportiere die Daten ohne die Feldbezeichner einfach als Array von Werten.
Delphi-Quellcode:
function TApiResource.GetPersonen: TJSONArray;
var LPersonen, LPersonenRec: TJSONArray;
qrPersonen: TFDQuery;
begin
LPersonen := TJSONArray.Create;
qrPersonen := FD.CreateQuery('');
qrPersonen.open;
while not qrPersonen.eof do
begin
LPersonenRec := TJSONArray.Create;
LPersonenRec.add(qrPersonen.FieldByName('PERSONID').AsLargeInt);
LPersonenRec.add(qrPersonen.FieldByName('NAMEN').AsString);
LPersonenRec.add(qrPersonen.FieldByName('TITEL').AsString);
LPersonenRec.add(qrPersonen.FieldByName('VORNAME').AsString);
LPersonenRec.add(qrPersonen.FieldByName('GEBURTSDATUM').AsString);
LPersonenRec.add(qrPersonen.FieldByName('PERSONALNR').AsString);
LPersonenRec.add(qrPersonen.FieldByName('EINTRITTJAHR').AsInteger);
LPersonenRec.add(qrPersonen.FieldByName('FACHNR').AsLargeInt);
LPersonenRec.add(qrPersonen.FieldByName('FACH').AsString);
LPersonen.Add(LPersonenRec);
qrPersonen.next;
end;
result := LPersonen;
end;
Dieser Vorgang dauert jedoch deutlich länger als wenn ich das TFDQuery direkt ausgebe.
Wenn ich die Methode umbaue auch
Code:
SELECT FIRST 10000 SKIP 10000 *...
dann dauert es insgesamt noch länger da das vorbereiten der
Query erneut durchgeführt wird für alle 10000 Records. Die
Query ist in dem Beispiel ohne Where und joins. Ich Wirklichkeit ist die
Query also komplexer.
Dann dachte ich, ich erzeuge eben bei einer Anfrage eine JSON in einem anonymen Thread und schreibe es in ein File. Über eine zweite Methode rufe ich dann das File als Stream ab. Das funktioniert leider auch nicht da ich innerhalb des anonymen Threads auf das FD Object
FD.CreateQuery('');
nicht zugreifen kann. Wenn das gehen würde, wäre das perfekt da das File im Hintergrund erzeug werden würde und ich nur periodisch nach dem File frage könnte.