AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Einfügen über externalTabelle funktioniert nicht richtig

Einfügen über externalTabelle funktioniert nicht richtig

Ein Thema von blutigerAnfänger · begonnen am 27. Feb 2014 · letzter Beitrag vom 12. Sep 2014
Antwort Antwort
Seite 3 von 5     123 45   
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.534 Beiträge
 
Delphi 11 Alexandria
 
#21

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 28. Feb 2014, 08:46
Kannst du mir diese Quelle zeigen, in der beschrieben wird, wie man eine reine Textdatei ohne SQL-Befehle in die Datenbank einliest?
Firebird: http://www.firebirdfaq.org/faq209/
MySQL: http://www.little-idiot.de/mysql/mysql-121.html
Oracle: http://docs.oracle.com/cd/B10500_01/...96652/ch12.htm
Weiter habe ich jetzt nicht recherchiert. Das hat mit ständiger Verfügbarkeit usw. überhaupt nichts zu tun, sondern es geht tatsächlich um das schnelle Einlesen größerer Datenmengen aus einer externen Quelle. Auf der Zielseite braucht man natürlich SQL, aber für diesen Zweck ist es eben eine spezielle Syntax.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#22

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 28. Feb 2014, 09:19
Danke, DeddyH, das erweitert meinen Horizont.
  Mit Zitat antworten Zitat
blutigerAnfänger

Registriert seit: 23. Mär 2010
82 Beiträge
 
#23

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 1. Mär 2014, 13:36
Hallo

@Perlsau #19
Du wolltest wissen, um wieviele Datensätze es geht: 100.000 Stck. und mehr.
Dein Quelltext in Abwandlung funktioniert einwandfrei und rasendschnell. Wesentlich langsamer ist das Einlesen des SQL Scripts in IBExpert. Ich habe das mit der kompletten Tabelle ausprobiert und IBExpert benötigt 3 Minuten zum Einlesen von ca.100.000 Datensätzen.

Delphi-Quellcode:
Procedure TForm1.Einlesen();
Var
  MeineListe,
  HilfsListe,
  ZielListe : TStringList;
  Datei,
  Fremdwort,
  Beschreibung : String;
  i,z : Integer;

Begin
  MeineListe := TStringList.Create;

 Try
    MeineListe.LoadFromFile('kurz.txt');
    z := MeineListe.Count;
    ZielListe:= TStringList.Create;
    HilfsListe:= TStringList.Create;
    try
    For i := 0 to z-1 DO
    Begin
    HilfsListe.Text := StringReplace(MeineListe[i], #9, sLineBreak, [rfReplaceAll]);
      Beschreibung := HilfsListe[1];
      Fremdwort := HilfsListe[0];
    ZielListe.Add('Insert into Tabelle2 (Fremdwort,Beschreibung) values (' + QuotedStr(HilfsListe[0]) + ',' + QuotedStr(HilfsListe[1]) + ');');
    end;

  Finally
    MeineListe.Free;
    ZielListe.SaveToFile('ziel.sql');
    HilfsListe.Free;
    ZielListe.Free;

  End;
finally
end;
end;
Gibt es eine Möglichkeit, außerhalb der ZEOS Komponenten welche ich nicht nutze, den Script einzulesen und auszuführen?.

Delphi-Quellcode:
procedure TForm1.LadezielsqlClick(Sender: TObject);
begin
   with IBQuery1 do
    begin
       Active:=False;
       SQL.Clear;
       SQL.LoadFromFile('ziel.sql');
       ExecSQL;
       IBTransaction1.Commit;
    end;
end;
Hier hab bereits nach der ersten Zeile Error Code -104 Token unknown -line 2, Column 1 Insert.



Ach im Übrigen wir sind jetzt sehr weit weg von meiner Ausgangsfrage.

Geändert von blutigerAnfänger ( 1. Mär 2014 um 14:06 Uhr) Grund: Vervollständigung
  Mit Zitat antworten Zitat
blutigerAnfänger

Registriert seit: 23. Mär 2010
82 Beiträge
 
#24

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 2. Mär 2014, 18:17
Hallo

@Perlsau
Nach der Neuinstallation der IBX Komponenten, habe ich jetzt die IBScript Komponente zur Verfügung. Und damit folgende Lösung erbastelt.

Delphi-Quellcode:
procedure TForm1.LadezielsqlClick(Sender: TObject);
var
  startzeit,
  stopzeit : TDateTime;
  i:Integer;
begin
startzeit :=Now;
ibdb1.Open;
IBScript.Script.LoadFromFile('ziel.sql');
IBScript.ExecuteScript;
IBTransaction1.Commit;
stopzeit :=Now;
Panel1.Caption :='SuchZeit : '+ FormatDateTime('nn:ss:zzz', StopZeit - StartZeit) ;
end;
Um meine 100.000 Datensätze einzulesen, brauche ich jetzt ca. 2,5 Minuten. IBExpert brauchte 3 Minuten.

Nochmals external Tabellen:

Nach langen Herumprobieren hab ich die Lösung:

Falsch ist:
Delphi-Quellcode:
procedure TForm1.btn3Click(Sender: TObject);
begin
  with IBQuery1 do
   begin
      Active:=False;
      sql.Clear;
      sql.Text := 'Create TABLE dat_ext external file''c:\externalTables\Tabelle2.txt''(feld001 varchar(50), FELD002 VARCHAR(250), crlf char(2) )';
      Active:=true;
      IBTransaction1.Commit;
   end;
end;
Richtig ist:
Delphi-Quellcode:
procedure TForm1.btn3Click(Sender: TObject);
begin
  with IBQuery1 do
   begin
      Active:=False;
      sql.Clear;
      sql.Text := 'Create TABLE dat_ext external file''c:\externalTables\Tabelle2.txt''(feld001 char(50), FELD002 CHAR(250), crlf char(2) )';
      Active:=true;
      IBTransaction1.Commit;
   end;
end;
Der Unterschied: char statt varchar.

Zeitliche Verbesserung des Datenimports: SQLScript : 2,5 Minuten, ExternalTabelle : weniger als 5 Sekunden.

Dank an Borwin der das schon in #3 erkannt hat.

Dennoch, auf diese Art und Weise habe ich eine weitere Importmöglichkeit, InsertScript, in Erstellung und Nutzung kennengelernt.
Danke Perlsau.
  Mit Zitat antworten Zitat
blutigerAnfänger

Registriert seit: 23. Mär 2010
82 Beiträge
 
#25

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 7. Sep 2014, 22:37
Erneut external Dateien


Delphi-Quellcode:
procedure TForm1.btn3Click(Sender: TObject);
begin
  with IBQuery1 do
   begin
      Active:=False;
      sql.Clear;
      sql.Text := 'Create TABLE dat_ext external file''c:\externalTables\Tabelle2.txt''(feld001 char(50), FELD002 CHAR(250), crlf char(2) )';
      Active:=true;
      IBTransaction1.Commit;
   end;
end;
Dies ist der richtige Code für die Erstellung eines external Files, bestehend aus 2 Spalten von Strings.

Frage: Wie sieht der Code aus für 4 Spalten, bestehend aus 2 Spalten Strings, 1er Spalte Integer und 1er Spalte ID (Autoinc)?

Mittlerweile habe ich diesen fehlerhaften Code:
Delphi-Quellcode:
      sql.Clear;
      sql.Text := 'Create TABLE dat_ext external file''c:\db\import.txt''( checkbox integer ,name CHAR(50), bezeichnung CHAR(250), crlf CHAR(2) )';
      Active:=true;
      IBTransaction1.Commit;
      Active:=False;
      sql.Clear;
      sql.Text := 'Insert into Tabelle2 SELECT checkbox , name, bezeichnung from dat_ext ';
      Active:=true;
      IBTransaction1.Commit;
Soweit wie ich inzwischen weiß, wird die Spalte ID(Autoinc) erst nach dem Import der Daten ausgefüllt. Die Tabelle muß aber diese Spalte enthalten.

Code:
      sql.text := 'CREATE TABLE Tabelle2 (checkbox INTEGER, name VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE DE_DE, bezeichnung VARCHAR(250) CHARACTER SET ISO8859_1 COLLATE DE_DE , ID INTEGER)';
Fehler: da kann ich sagen siehe Beitrag #10
Kann Firebird externalFiles überhaupt mit Integer Feldern erstellen? Es sind viele teils widersprüchliche Ergebnisse zu finden, nur großteils Englisch.
Ich hoffe auf Eure Hilfe.
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#26

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 8. Sep 2014, 07:55
Externe Tabellen sind nicht dazu da, die Daten in einer endgültigen Form zu enthalten. Sie dienen nur zum Import. Du beschreibst also mit dem 'CREATE TABLE' nur den Aufbau deiner Datei und importierst sie dann in eine andere Tabelle, wobei Du die notwendigen Transformationen vornimmst (Char => Integer, Float, DateTime etc.). Aus diesem Grund ist es auch überflüssig und falsch, einen Autoinc Wert in der externen Tabelle vorhalten zu wollen.
  Mit Zitat antworten Zitat
blutigerAnfänger

Registriert seit: 23. Mär 2010
82 Beiträge
 
#27

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 8. Sep 2014, 09:35
..., wobei Du die notwendigen Transformationen vornimmst (Char => Integer, Float, DateTime etc.). Aus diesem Grund ist es auch überflüssig und falsch, einen Autoinc Wert in der externen Tabelle vorhalten zu wollen.
Notwendige Transformationen sind das Stichwort.
String --> CHAR --> VARCHAR
INTEGER --> ??? --> INTEGER

Also Ich habe eine Tabelle mit 3 Feldern (Integer, String, String). Die Stringfelder werden als CHAR bezeichnet und in der endgültigen Firebird Tabelle zu VARCHAR transformiert. Wie mache ich das mit Integer?
INTEGER zu CHAR gibt es Konversionsfehler und INTEGER mit Längenbezeichnung zB. INTEGER(10) ist Blödsinn.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#28

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 8. Sep 2014, 09:41
Externe Tabellen sind nicht dazu da, die Daten in einer endgültigen Form zu enthalten. Sie dienen nur zum Import. Du beschreibst also mit dem 'CREATE TABLE' nur den Aufbau deiner Datei und importierst sie dann in eine andere Tabelle, wobei Du die notwendigen Transformationen vornimmst (Char => Integer, Float, DateTime etc.). Aus diesem Grund ist es auch überflüssig und falsch, einen Autoinc Wert in der externen Tabelle vorhalten zu wollen.


Ich möchte noch ergänzen, dass das Bedürfnis nach einer eindeutigen ID natürlich legitim ist. Was und wie Du aber auch immer importierst, die zu importierenden Daten sollten über solch ein eindeutiges Merkmal bereits verfügen, notfalls über mehrere Felder und idealer Weise auch gegenüber den bereits importierten Daten. Ansonsten holst Du Dir die Leichen reihenweise in den Keller.

Schau Dir mal Literatur zum Thema ETL an. Ganz grob:
Daten temporär in der DB bereitstellen (z.B. via ExternalTable)
Daten aufbereiten (z.B. Dubletten entfernen, plus Rückmeldung / Log)
Daten dann mit System-/Produktivdaten abgleichen und ggF. importieren.
Dabei gehst Du sehr wahrscheinlich Satz für Satz durch die neuen Daten und schaust wo und wie Du sie unterbringst. (Wiederum mit Rückmeldung bzw. Log für automatisierte Prozesse)

Konvertierung:
Es ist stark anzunehmen, dass Deine CSV Daten im Klartext dort stehen und Integer bspw nicht 2 oder 4 Byte binär codiert sind.
Also Integer auch als Varchar einlesen mit Längenangabe entsprechend dem CSV.
P.S.: Wenn Du aus der DB dann auf die "integer" Daten zugreifst, musst Du konvertieren.
Also beim Insert in die Zieltabelle z.B..
Gruß, Jo
  Mit Zitat antworten Zitat
blutigerAnfänger

Registriert seit: 23. Mär 2010
82 Beiträge
 
#29

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 8. Sep 2014, 17:25
Ich möchte noch ergänzen, dass das Bedürfnis nach einer eindeutigen ID natürlich legitim ist. Was und wie Du aber auch immer importierst, die zu importierenden Daten sollten über solch ein eindeutiges Merkmal bereits verfügen, notfalls über mehrere Felder und idealer Weise auch gegenüber den bereits importierten Daten. Ansonsten holst Du Dir die Leichen reihenweise in den Keller.

Schau Dir mal Literatur zum Thema ETL an. Ganz grob:
Daten temporär in der DB bereitstellen (z.B. via ExternalTable)
Daten aufbereiten (z.B. Dubletten entfernen, plus Rückmeldung / Log)
Daten dann mit System-/Produktivdaten abgleichen und ggF. importieren.
Dabei gehst Du sehr wahrscheinlich Satz für Satz durch die neuen Daten und schaust wo und wie Du sie unterbringst. (Wiederum mit Rückmeldung bzw. Log für automatisierte Prozesse)

Konvertierung:
Es ist stark anzunehmen, dass Deine CSV Daten im Klartext dort stehen und Integer bspw nicht 2 oder 4 Byte binär codiert sind.
Also Integer auch als Varchar einlesen mit Längenangabe entsprechend dem CSV.
P.S.: Wenn Du aus der DB dann auf die "integer" Daten zugreifst, musst Du konvertieren.
Also beim Insert in die Zieltabelle z.B..
Zum 1ten Absatz:
Also am besten mit einem 2ten Integer Feld (in dem bereits die Autoinc enthalten ist)??

zum 2ten Absatz:
Nenn mir doch mal eine deutschsprachige Literatur zum Thema ETL (externalTabelle?), welche möglichst einfach gehalten ist. Vielleicht gibt's da noch etwas was ich bei meiner Recherche übersehen habe.

zum 3tenAbsatz (Konvertierung):
Anbei zwei Screenshots, beide zeigen die Ergebnisse der external Tabelle aus IBexpert personnel.
Der eine Screenshot zeigt das Importergebnis von CHAR, der andere das Importergebnis von VARCHAR an beide mit Länge 10.
Miniaturansicht angehängter Grafiken
importmitchar10.png   importmitvarchar10.png  
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#30

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 8. Sep 2014, 17:27
Und wie sieht die Datei aus?
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 09:19 Uhr.
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