![]() |
unbestimmte Anzahl TFDQuerys abgleichen
Moin!
Ich habe eine Frage zur potentiellen Performance und Erfahrungen eurerseits. Situation: Ich habe eine unbestimmte Anzahl von Querys, welche jeweils eine ID-Spalte halten. Die Daten sind vorsortiert. Über alle Querys muss ich die ID-Übereinstimmungen finden. Mit Dem Ergebnis will ich eine SQL-Abfrage füttern. Ich könnte einfach alle IDs aus einer Querys nehmen und jeweils einen Abgleich des gewünschten Feldes für diese durchführen. Das könnte aber zu sehr langen SQL-Strings führen. Entsprechend will ich dort eine Vorverarbeitung durchführen. Eine Überführung der IDs in int-Arrays erscheint mir von den Arbeitsschritten her eigentlich unnötig. Ich mache jetzt das: - Querys auf Beschaffenheit kontrollieren und nur die weiter betrachten, die wichtig sind - Wenn nur eine Query übrig bleibt kann ich die IDs dieser einfach verarbeiten - Wenn mehrere Querys übrig bleiben suche ich mir die längste, um eine übergreifende Schleife zu starten -- Ich kontrolliere die aktuellen Daten über alle Query auf Gleichheit --- bei Erfolg habe ich eine ID gefunden --- bei Fehlschlag schaue ich mir die IDs aller Querys an und schreite voran, solang die IDs der zu überprüfenden Querys kleiner sind als die der Schleifen-Query --- am Ende schreite ich einen Datensatz in der Schleifen-Query weiter und die Checks beginnen erneut Die Tests schauen soweit gut aus. Geht das ganze aber effektiver / schneller?
Delphi-Quellcode:
function func_findPoiIds(sArrIdField : TArray<String>; quArrData : TArray<TFDQuery>) : String;
var sIdFieldLong : String; quDataLong : TFDQuery; bQuAction : Boolean; i, iPos : Integer; begin Result := '0'; if Length(sArrIdField) <> Length(quArrData) then Exit; //Start Entfernen leerer Elemente i := 0; while i < Length(quArrData) do begin if quArrData[i].IsEmpty then begin Delete(quArrData, i, 1); Delete(sArrIdField, i, 1); Dec(i); end; Inc(i); end; if Length(sArrIdField) <> Length(quArrData) then Exit; //Ende Entfernen leerer Elemente //Start nur ein Element übrig if Length(quArrData) = 1 then begin quArrData[0].First; while not quArrData[0].Eof do begin Result := Result + ',' + quArrData[0].FieldByName(sArrIdField[0]).AsString; quArrData[0].Next; end; Exit; end; //Ende nur ein Element übrig //Start Längstes Element finden iPos := 0; for i := 1 to Length(quArrData)-1 do if quArrData[i].RecordCount > quArrData[iPos].RecordCount then iPos := i; sIdFieldLong := sArrIdField[iPos]; Delete(sArrIdField, iPos, 1); quDataLong := quArrData[iPos]; quDataLong.First; Delete(quArrData, iPos, 1); for i := 0 to Length(quArrData)-1 do quArrData[i].First; //Ende Längstes Element finden //Start QueryVergleich while not quDataLong.Eof do begin //Start ID anfügen und weiter springen bQuAction := true; for i := 0 to Length(quArrData)-1 do if quDataLong.FieldByName(sIdFieldLong).AsInteger <> quArrData[i].FieldByName(sArrIdField[i]).AsInteger then begin bQuAction := false; Break; end; if bQuAction then begin Result := Result + ',' + quDataLong.FieldByName(sIdFieldLong).AsString; quDataLong.Next; for i := 0 to Length(quArrData)-1 do quArrData[i].Next; Continue; end; //Ende ID anfügen und weiter springen //Start QuerryData hochsetzen for i := 0 to Length(quArrData)-1 do begin bQuAction := false; while not quArrData[i].Eof and (quDataLong.FieldByName(sIdFieldLong).AsInteger > quArrData[i].FieldByName(sArrIdField[i]).AsInteger) do begin quArrData[i].Next; bQuAction := true; end; if bQuAction then Break; end; //nach PositionsVeränderung neue Prüfung einleiten if bQuAction then Continue; //Ende QuerryData hochsetzen quDataLong.Next; end; //Ende QueryVergleich end; |
AW: unbestimmte Anzahl TFDQuerys abgleichen
Hängen da auch noch paar Edits/Grids an diesen DataSets?
Dann ist es natürlich langsam, wenn man währenddessen nicht mit DisableControls arbeitet. Und warum àlles manuell durchscrollen und die ID suchen, anstatt Locate zu benutzen? Vom Tempo her ist es fast egal, auch wenn rückwärts natürlich dennoch schneller ist, weil insgesamt im Array weniger einträge verschoben werden müssen. Und zusätzlich ist der Code auch noch wesentlich kürzer/übersichtlicher. Zitat:
Delphi-Quellcode:
for i := High(quArrData) downto 0 do
if quArrData[i].IsEmpty then begin Delete(quArrData, i, 1); Delete(sArrIdField, i, 1); end; Zitat:
Delphi-Quellcode:
[edit]
//bQuAction := quArrData[i].Locate(sArrIdField[i], quDataLong.FieldByName(sIdFieldLong).AsInteger);
bQuAction := quArrData[i].LocateEx(sArrIdField[i], quDataLong.FieldByName(sIdFieldLong).AsInteger, [lxNext]); if bQuAction then Break; Ich seh grad, es war hier kein <> sondern > und Locate arbeitet natürlich wie =, also das Gegenteil von <> :oops: Hatte hier zuerst die Schleife von
Delphi-Quellcode:
, welche aber über das Array und kein Dataset läuft.
//Start ID anfügen und weiter springen
Bei einem sortierten Array kann man könnte man aber ebenfalls ein TArray.BinarySearch verwenden. [/edit] PS: Was soll das Zweite
Delphi-Quellcode:
machen?
if Length(sArrIdField) <> Length(quArrData) then Exit;
Wenn es beim Ersten schon gleich war und dazwischen links und rechts genau gleichviel gelöscht wurde, dann kann es dort NIEMALS unterschiedlich sein. Ansonsten isses ein bissl schwer direkt zu erkennen, was nun genau gemacht wird, aber mit bissl kürzerem/übersichtlicherm Code versteht man es womöglich auch schneller. |
AW: unbestimmte Anzahl TFDQuerys abgleichen
Zitat:
Zitat:
Zitat:
Zitat:
Würde es an sich noch einen anderen Ansatz geben, der besser ist als meiner? (Außer die schon gefundenen Sachen natürlich. ;)) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz