AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Datenimport ohne Doppelte Daten mit SQL

Datenimport ohne Doppelte Daten mit SQL

Ein Thema von dUSER.th · begonnen am 1. Okt 2013 · letzter Beitrag vom 27. Okt 2013
Antwort Antwort
Seite 1 von 2  1 2   
dUSER.th

Registriert seit: 20. Jun 2008
24 Beiträge
 
#1

Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 09:35
Datenbank: EMS FireBird • Version: 1.5 • Zugriff über: Delphi 7 ZQuery
Hallo zusammen,

Ich habe 2 Tabellen.
Tabelle1 "TB_IMPORT"
wird mit Daten aus *.xls oder *.txt gefüllt.
Tabelle2 "TB_RP2013"
soll mit Daten aus Tabelle1 befüllt werden aber keine schon vorhandenen Daten.
In beiden Tabellen gibt es das Feld "BEWNR" = Bewegnummer was eindeutig ist.

Mein momentaner Ansatz.

Delphi-Quellcode:
  
  DBF2 := ZQuery2;
  DBF3 := ZQuery3;
  vJAHR:= '2013';

  with DBF2 do begin
    SQL.Clear;
    SQL.Text:= 'SELECT '+
                 'TB_IMPORT.GEBUCHT, '+
                 'COUNT(TB_IMPORT.BEWNR) AS DOPPELT, '+
                 'TB_RP'+vJAHR+'.BEWNR '+
                'FROM '+
                'TB_IMPORT '+
                'INNER JOIN TB_RP'+vJAHR+' ON (TB_IMPORT.BEWNR=TB_RP'+vJAHR+'.BEWNR) '+
                'GROUP BY '+
                 'TB_IMPORT.GEBUCHT, '+
                 'TB_RP'+vJAHR+'.BEWNR';
    DBF2.Active:= True;
    Form1.ProgressBar1.Max:= DBF2.RecordCount;
    while NOT DBF2.Eof do begin
      vBEWNR := DBF2.FieldValues['BEWNR'];
      Form1.ProgressBar1.Position:= DBF2.RecNo;

      with DBF3 do begin
        SQL.Clear;
        SQL.Text:= 'UPDATE TB_IMPORT SET GEBUCHT = 1 WHERE '+
                    'TB_IMPORT.BEWNR = ' + vBEWNR;
        DBF3.ExecSQL;
      end;
      Label3.Caption:= IntToStr(DBF2.RecordCount);
      Form1.Repaint;
      DBF2.Next;
    end;
  end;
Es werden alle 2 Stunden cs. 10.000 Daten eingelesen was mit unter sehr langsam ist.
Ich denke, ich hatte das schon mal schneller. Nur leider sind von meiner 1. Version verschiedene Units verloren gegangen. Ich habe nur noch die *.exe Datei aber da finde ich nicht alles.

Habt Ihr eventuell einen hinweis was ich noch ändern sollte oder kann?
Vielen Dank
  Mit Zitat antworten Zitat
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#2

AW: Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 09:42
1. arbeite mit Transaktionen
1.1. damit die Transaktion nicht zu groß wird, kannst du nach X Datensätzen ein commit ausführen. Nach wie vielen Datensätzen genau der richtige Zeitpunkt ist, musst du ausprobieren
2. arbeite mit prepared-statements
2.1. dafür musst du auch mit Parametern arbeiten, statt dir den SQL-Befehl ständig neu zusammenzubasteln...
3. nach jedem Datensatz ein Repaint? Ich würde das Repaint vielleicht nur nach allen 500 Datensätzen oder so durchführen (falls überhaupt erforderlich)
  Mit Zitat antworten Zitat
weisswe
(Gast)

n/a Beiträge
 
#3

AW: Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 09:51
Hallo!

Habe zwar noch nicht mit einer Firebird DB gearbeitet, aber in anderen Datenbanken ist die Syntax so oder so ähnlich:
Code:
insert [felder] into tab2 from
(select [felder] from tab1 alias1 where not exists
 (select [felder] from tab2 where key = alias1.key)
)
Grüße,
Werner
  Mit Zitat antworten Zitat
dUSER.th

Registriert seit: 20. Jun 2008
24 Beiträge
 
#4

AW: Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 10:02
Ups das ging aber schnell,

vielen Dank erst mal.

#Morphie
P3. Das anzeigen der RecordCount kommt wieder raus, ist nur momentan zur anzeige.

P1 bis P2.1 komm ich jetzt nicht so ganz mit.
Es soll nur der doppelte Satz mit einem Zeichen markiert werden. Lieber währe es mir ich kann den Satz gleich Löschen. Aber das ist ja warum auch immer noch langsamer.

Könntest Du mir mit P1 mal einen kleinen weiteren Tip geben?

#weisswe

Das hatte ich auch schon durch hierbei brauch die DB ca. 1 Std bei 9400 Sätzen.
Warum auch immer.

Vielen Dank
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.802 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 10:06
U.U. bietet sich hier ein MERGE oder UPDATE OR INSERT an
Markus Kinzler
  Mit Zitat antworten Zitat
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#6

AW: Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 11:17
P1 bis P2.1 komm ich jetzt nicht so ganz mit.
Es soll nur der doppelte Satz mit einem Zeichen markiert werden. Lieber währe es mir ich kann den Satz gleich Löschen. Aber das ist ja warum auch immer noch langsamer.

Könntest Du mir mit P1 mal einen kleinen weiteren Tip geben?
P1:
Ich weiß nicht genau wie ZEOS das intern macht, aber ich vermute, wenn du keine Transaktion explizit angibst / erzeugst, erzeugt ZEOS eine Transaktion automatisch.
In deinem Beispiel würde ZEOS automatisch für jeden Datensatz eine eigene Transaktion erzeugen. Das ist natürlich nicht sinnvoll...
Du müsstest dir also zu Beginn der Methode eine Transaktion erzeugen, dem Query zuordnen und am ende (oder zwischendurch) ein Commit (Speichern) der Transaktion durchführen.

P2.1:
Du setzt in jedem Schleifendurchlauf (Datensatz) den Commandtext für DBF3 neu. Den solltest du aber nur einmalig vor der Schleife setzen:
Code:
UPDATE TB_IMPORT SET GEBUCHT = 1 WHERE TB_IMPORT.BEWNR = :PAR_BEWNR;
anschließend ein DBF3.Prepare; um den Befehl zur Datenbank zu schicken.
In dem Moment weiß die Datenbank genau, was sie machen soll. Ihr fehlen aber noch die entsprechenden Datensätze / Werte.
Also füllst du jetzt innerhalb der Schleife den Parameter "AR_BEWNR" mit deiner Variable vBEWNR und führst ein Execute durch.

Wenn du das so machst, hast du gleich mehrere Vorteile:
1. du verringerst den Traffic zum Datenbankserver.
2. der Server weiß bereits, was er zutun hat, muss den Befehl also nicht jedes Mal neu parsen.
3. du kannst dir so keine SQL-Injections einfangen...
  Mit Zitat antworten Zitat
hstreicher

Registriert seit: 21. Nov 2009
219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

AW: Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 13:08
Ups das ging aber schnell,

#weisswe

Das hatte ich auch schon durch hierbei brauch die DB ca. 1 Std bei 9400 Sätzen.
Warum auch immer.

Vielen Dank
ist den ein Index auf das Feld BEWNR angelegt ?

@mkinzler

"update or insert" geht nicht mit seiner 1.5 er Version
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.332 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 13:35
Wenn es hier im Gegensatz zu Überschrift nur darum geht bereits vorhandene Datensätze zu kennzeichnen, genügt dann nicht ein Befehl an die Datenbank?
Code:
update tb_import a
set   a.gebucht = (select count(b.bewnr) from tb_rp2013 b where (b.bewnr = a.bewnr))
In der Tabelle "tb_rp2013" sollte ein eindeutiger Index auf "bewnr" vorhanden sein.
  Mit Zitat antworten Zitat
dUSER.th

Registriert seit: 20. Jun 2008
24 Beiträge
 
#9

AW: Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 17:35
Hallo zusammen,

Stimmt, meine Überschrift zum Thema ist in dem Sinne Falsch.
Sorry mein Fehler ich habe schon zuweit gedacht.

Die Daten die Doppelt sin sollen gekennzeichnet werden.
Einen Index kann ich nicht auf das Feld "BEWNR" legen, weil in der Tabelle TB_RP2013
die Bewegnummer durchaus Doppelt sein kann. Diese habe dann aber einen Präfix.
Und nur die Daten aus der Importtabelle dürfen nicht doppelt vorkommen.
Ist schon etwas verrückt, aber es soll so sein.

Ich hatte jetzt mal den Code von #hstreicher mit den EMS FireBird Manager getestet.
Der Code wurde angenommen aber nach ca. 1 1/2 Std. hat sich mein Server wegen Überhitzung erstmal verabschiedet.
Nun habe ich erst mal Serverprobleme die ich beheben muss und melde mich wieder, wenn alles wieder Funktioniert.

Erst mal Vielen Dank für die Hilfe
bis Später
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.802 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Datenimport ohne Doppelte Daten mit SQL

  Alt 1. Okt 2013, 17:45
Zitat:
Einen Index kann ich nicht auf das Feld "BEWNR" legen, weil in der Tabelle TB_RP2013
die Bewegnummer durchaus Doppelt sein kann.
Das verhindert aber keinen Index
Markus Kinzler
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf