Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen (https://www.delphipraxis.net/174980-konzeptfrage-zu-sql-schleife-auf-bedingung-pruefen.html)

juergen 22. Mai 2013 19:23

Datenbank: Pervasive • Version: egal • Zugriff über: egal

Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
Hallo zusammen,
ich muss eine Anforderung umsetzen und suche nun eine passende "Strategie".
Gegeben: 1 größere Tabelle, eine Textdatei mit ca. 200 - 3000 Rec-ID-Nummern. Die Tabelle hat momentan ca. 600 000 Datensätze, täglich wachsend.
Nun soll in dieser Tabelle in allen Datensätzen welche einer der Rec-Id's (Identifikation) aus der Textdatei entsprechen, ein bestimmtes Feld gesetzt werden.

Im ersten Ansatz würde ich mir die Textdatei mit den Identifikations-Nummern in eine StringList laden.
Dann in einer Schleife durchlaufen lassen.
Pseudo-Code:
Delphi-Quellcode:
begin
  Qry_Update.SQL.add(UPDATE MEINETABELLE set MEINETABELLE.UpdateFeld = '8' where MEINETABELLE.Identifikation = );
    begin
      Sl_sql := TStringList.Create;
      Sl_sql.LoadFromFile(...);
      for I := 0 to Sl_sql.Count - 1 do begin
        if I <> Sl_sql.Count - 1 then begin
          Qry_Update.SQL.add('Sl_sql[i] or MEINETABELLE.Identifikation = ')
        end else Qry_Update.SQL.add('Sl_sql[i]')
      end;
    end;
end;
Ich habe das jetzt nicht getestet und habe auch keine Vorstellung wie performant das Ganze ist und ob es so überhaupt sinnvoll ist.

Kennt jemand bessere Konzepte für solche Anforderungen oder sollte ich das so umsetzen?

Vielen Dank schon mal vorab für eure Unterstützung!

Furtbichler 22. Mai 2013 19:50

AW: Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
Importiere die Liste mit den IDs in die Datenbank. Nennen wir diese Tabelle 'IDTabelle'. Dann erstellst Du einen Index auf die Spalte. Nun führst Du einfach einen SQL-Befehl aus:

Code:
update Tabelle Set Feld=1
  where ID in (select * from IDTabelle)
Anschließend löschst Du die Tabelle wieder. Der Import der Textdatei sollte sehr schnell mit BDU.EXE möglich sein, welches ab v9 mitgeliefert wird.

sx2008 22. Mai 2013 19:57

AW: Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
Ich würde dazu die IN-Klausel nützen:
SQL-Code:
UPDATE MEINETABELLE set MEINETABELLE.UpdateFeld = '8' where MEINETABELLE.Identifikation IN (4711,4712,4713,4714)
Schreib dir eine Funktion, die immer 50 Werte aus der Stringliste mit REC-ID-Nummern entnimmt (und auch gleich aus der Stringliste entfernt).
Du kannst nicht alle 2000-3000 Werte in die IN-Klausel packen, weil dann bestimmte Limits wie z.B. max Länge einer SQL-Anweisung übrschritten würden.

Furtbichler 22. Mai 2013 20:06

AW: Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
Bei 200-3000 IDs könnte das wirklich schneller sein.. ich kann mir vorstellen, das Pervasive mit durchaus 100 IDs in der IN-Liste klar kommt. Dann wären das 2-30 statements...

juergen 22. Mai 2013 20:13

AW: Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
@Furtbichler,
oh da staune ich, du kennst das Pervasive BDU-Tool, da höre ich heute zum ersten Mal von. :-D. Laut Pervasive-Hilfe scheint das Tool ja schön simpel zu sein. Gut zu wissen...
Vielen Dank für deinen wirklich interessanten Tipp und Ansatz mit der 2.Tabelle! :thumb:

@sx2008,
vielen Dank auch für deinen Tipp! :thumb:
Dein Ansatz könnte ich wohl relativ schnell umsetzen, aber irgendwie reizt mich jetzt der Ansatz von Furtbichler

Euch einen schönen Abend! :dp:

juergen 22. Mai 2013 20:48

AW: Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
Ich habe das ganze nun direkt mit 3000(!) 8-stelligen Rec-Id's in einem SQL-Statement über die IN Bedingung ausgeführt. Das funktioniert! Dauert ca. 1,5 Sekunden. Danach habe ich es wiederholt mit 6 stelligen Rec-Id's, da sah ich auch das Ergebnis (meine Test-Tabelle hat ja nur 600 000 Datensätze).

Was meint ihr, sollte ich das trotzdem "aufbröseln" in kleine Häppchen, also in mehrere SQL-Statements?
Ich finde in der Hilfe keine Limitierungen.

nahpets 22. Mai 2013 22:06

AW: Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
Zitat:

Zitat von juergen (Beitrag 1216117)
..., aber irgendwie reizt mich jetzt der Ansatz von Furtbichler

Das dürfte die bessere Alternative sein, da es hier keine Einschränkungen für SQL, Where- oder IN-Klausel geben und der geringste Aufwand sein dürfte.

Datei in Tabelle einlesen.
Update ausführen
Tabelle leeren

Unter Oracle machen wir das immer so:

Batch-/Shellscript mit (ggfls. per Taskplaner...)

Datei(en) woher auch immer per FTP... holen (wenn erforderlich)
SQLLoader zum Befüllen (temporärer) Tabelle(n)
SQLPLus mit Datenbankscript zur Verarbeitung der soeben geladenen Daten incl. aufräumen der (temporären) Tabellen
verarbeitete Datei(en) sichern oder entsorgen, je nach Aufgabenstellung

Wir machen möglichst viele Aufgaben direkt in der Datenbank, da dies gewöhnlich deutlich schneller ist, als über Programme.

Furtbichler 23. Mai 2013 06:46

AW: Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
Zitat:

Zitat von juergen (Beitrag 1216120)
Was meint ihr, sollte ich das trotzdem "aufbröseln" in kleine Häppchen, also in mehrere SQL-Statements?
Ich finde in der Hilfe keine Limitierungen.

Ja, mach das. Wenn bei dir die 3000 funktionieren, bitte sehr. Und die 1,5s könnte man zwar theoretisch unterbinden, aber wozu. Ich kann mir vorstellen, das die BDU-Lösung bei den paar IDs, mit denen du derzeit in der Textdatei hantierst, auch nicht schneller ist.

Als Übung wäre es jedoch eine gute Sache. Es ist immer praktisch, ein Bulk Insert Tool im Schrank zu haben.

jobo 23. Mai 2013 07:53

AW: Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
Liegen die Daten als Import vor, wäre das Stichwort 'korreliertes Update'
Code:
UPDATE <Tabelle | View>
   SET <Name einer Spalte> = <Ausdruck aus Spalten,
      Konstanten, Funktionen>
      [, weitere Spaltennamen = Ausdruck]
   [FROM <Tabelle> [INNER | LEFT | RIGHT] JOIN <Tabelle>
   ON <Spalte-1 = Spalte-2>]
   WHERE <Bedingung>
Dieses Verfahren dürfte in keinem etablierten RDBMS zu einer Verletzung von Limitierungen führen. Dieses Verfahren lässt sich auch einfach erweitern, wenn es mehrere Kriterien für den eigentlichen Abgleich gibt. 'Where In ()' ist da je nach System nicht so flexibel.
Bleibt als fragwürdige Hürde nur der Kodierungs-Aufwand für den Import.
Vom Performancespekt her ist die Import/korreliertes Update Lösung garantiert unschlagbar. Wenn es um große Datenmengen geht, setzen wir bspw. vor den Import ein gezipptes Upload.
Je nach Importverfahren /-fähigkeiten der DB ist nicht mal ein wirklicher Import notwendig (Stichwort 'external tables'). Man müllt sich die DB nicht zu und muss nichts anlegen/löschen. Die original csv-Dateien können bei Bedarf zu dokumentarischen Zwecken (gezippt) auf dem Serverfilesystem verbleiben.

juergen 23. Mai 2013 19:58

AW: Konzeptfrage zu SQL: in Schleife(?) auf Bedingung prüfen
 
@nahpets,
Zitat:

Zitat von nahpets (Beitrag 1216126)
Das dürfte die bessere Alternative sein, da es hier keine Einschränkungen für SQL, Where- oder IN-Klausel geben und der geringste Aufwand sein dürfte.

Gestern Nacht hatte ich erst einmal eine Version fertig gestellt, welche mit der IN()-Bedingung arbeitet, aufgeteilt in mehrere "Häppchen". Dabei kann ich nun von "außen" 2 Parameter übergeben:
1. maximale Anzahl der Übergabewerte in der IN() Bedingung (momentan habe ich beim Kunden 1000 eingestellt und das lief heute beim Kunden schon mal problemlos)
2. Die eigentlichen ID's für die IN() Bedingung

Nach diesem Wochenende (Stichwort Borussia :wink:) werde ich auf jeden Fall noch die "bessere" Variante von Furtbichler umsetzen. Schon allein um zu wissen wie das Pervasive eigene BDU-Tool arbeitet.
Zitat:

Zitat von Furtbichler (Beitrag 1216137)
Es ist immer praktisch, ein Bulk Insert Tool im Schrank zu haben.

:thumb:


@by jobo,
danke auch für deinen Tipp! :)
Auf den ersten Blick sieht das für mich nach dem aus, was Furtbichler in Post#2 vorgeschlagen, oder?


Ich bin nun froh dass ich meine Frage hier gestellt hatte, da ich hier 2 interessante neue Ansätze erhalten habe. Vielen Dank dafür! :dp:

..


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:01 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz