AGB  ·  Datenschutz  ·  Impressum  







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

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
Perlsau
(Gast)

n/a Beiträge
 
#1

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 27. Feb 2014, 19:48
Nun eine Frage zu deinem Quelltext: Datenmodul?? Steht in den Interbasekomponenten nicht drin.
Ein Datenmodul ist ein Container für Datenzugriffs-Komponenten. Du kannst ein neues Datenmodul genau so anlegen, wie du z.B. eine neue Form anlegst. Ich verwende das Datenmodul aber auch für die meisten Methoden, die mit dem direkten Datenzugriff zu tun haben. Natürlich mußt du deine Datenzugriffs-Komponenten nicht in einem Datenmodul unterbringen.

Offenbar willst du jetzt einen anderen Weg als externalFile einschlagen?
Ich hab keine Ahnung, welchen Weg du gegangen bist, um den Inhalt der Textdatei in deine Firebird-Datenbank zu bekommen, doch ganz offensichtlich war diese Methode fehlerhaft. Daher habe ich dir eine ganz einfache, übersichtliche Vorgehensweise gezeigt. Ob du das übernimmst oder dir was anderes überlegst, bleibt dir überlassen.

Es geht ja offenbar nicht darum, eine externe Datei zur ständigen Verfügung zu haben, wie das z.B. beim Einbinden einer external Table beabsichtigt ist, sondern um das Einlesen von Daten aus einer Textdatei in die Datenbank. Vermutlich willst du dir ein datenbankgestütztes Fremdwörterbuch bauen und dafür bereits vorhandene Fremdwort-Ressourcen verwenden. Das heißt, du willst die Inhalte nur einmal einlesen, danach benötigst du diese Textdatei nicht mehr. Anders wäre es, wenn du das ExternalFile benötigen würdest, weil irgend eine andere Anwendung diese External Table ständig aktualisiert. Bei External Table werden, soweit ich das verstanden habe, keine Kopien der Inhalte in der Datenbank angelegt, sondern das ExternalFile direkt als Speicher verwendet. Du aber möchtest die Daten der Textdatei in deiner Datenbank-Tabelle verfügbar haben.

Übrigens fehlt in meiner Methode noch eine Prüfung, ob das aktuell einzufügende Fremdwort bereits in der Datenbank existiert.
  Mit Zitat antworten Zitat
blutigerAnfänger

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

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 27. Feb 2014, 20:22
Ein Datenmodul ist ein Container für Datenzugriffs-Komponenten. Du kannst ein neues Datenmodul genau so anlegen, wie du z.B. eine neue Form anlegst. Ich verwende das Datenmodul aber auch für die meisten Methoden, die mit dem direkten Datenzugriff zu tun haben. Natürlich mußt du deine Datenzugriffs-Komponenten nicht in einem Datenmodul unterbringen.
Damit werde ich mich erst einmal eine Weile beschäftigen müssen.


Es geht ja offenbar nicht darum, eine externe Datei zur ständigen Verfügung zu haben, wie das z.B. beim Einbinden einer external Table beabsichtigt ist, sondern um das Einlesen von Daten aus einer Textdatei in die Datenbank. Vermutlich willst du dir ein datenbankgestütztes Fremdwörterbuch bauen und dafür bereits vorhandene Fremdwort-Ressourcen verwenden. Das heißt, du willst die Inhalte nur einmal einlesen, danach benötigst du diese Textdatei nicht mehr. Anders wäre es, wenn du das ExternalFile benötigen würdest, weil irgend eine andere Anwendung diese External Table ständig aktualisiert. Bei External Table werden, soweit ich das verstanden habe, keine Kopien der Inhalte in der Datenbank angelegt, sondern das ExternalFile direkt als Speicher verwendet. Du aber möchtest die Daten der Textdatei in deiner Datenbank-Tabelle verfügbar haben.
Wenn ich dich richtig verstanden habe, unterliegst du offenbar einem Irrtum. Es geht nicht darum, eine externe Datei zur ständigen Verfügung zu haben, sondern um das schnelle Einlesen von Daten (vielleicht ist Bulk Insert dazu das richtige Stichwort). Im Rahmen meiner Recherche habe ich irgendwo gelesen, daß die Orignale Textdatei(mit fixer Datensatzlänge) sozusagen als Block in die ExterneFirebirdTabelle übernommen wird. Daraufhin wird diese ExterneFirebirdTabelle in eine interne Tabelle verwandelt und die externe gelöscht.
Kurz gesagt es ist ein schnellerer Datenimport als das Einlesen jedes einzelnen Datensatzes per Insert...value...
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#3

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 27. Feb 2014, 20:41
Es geht ja offenbar nicht darum, eine externe Datei zur ständigen Verfügung zu haben, wie das z.B. beim Einbinden einer external Table beabsichtigt ist, sondern um das Einlesen von Daten aus einer Textdatei in die Datenbank. Vermutlich willst du dir ein datenbankgestütztes Fremdwörterbuch bauen und dafür bereits vorhandene Fremdwort-Ressourcen verwenden. Das heißt, du willst die Inhalte nur einmal einlesen, danach benötigst du diese Textdatei nicht mehr. Anders wäre es, wenn du das ExternalFile benötigen würdest, weil irgend eine andere Anwendung diese External Table ständig aktualisiert. Bei External Table werden, soweit ich das verstanden habe, keine Kopien der Inhalte in der Datenbank angelegt, sondern das ExternalFile direkt als Speicher verwendet. Du aber möchtest die Daten der Textdatei in deiner Datenbank-Tabelle verfügbar haben.
Wenn ich dich richtig verstanden habe, unterliegst du offenbar einem Irrtum. Es geht nicht darum, eine externe Datei zur ständigen Verfügung zu haben, sondern um das schnelle Einlesen von Daten (vielleicht ist Bulk Insert dazu das richtige Stichwort).
Aber genau das schrieb ich oben doch! Der Grund, eine External Table einzubinden, kann nur der sein, eine externe Datei zur ständigen Verfügung zu haben. Mit deinem Hinweis im ersten Post plus der Bemerkung von mkinzler ist bei mir erstmal dieser Eindruck entstanden. Dann habe ich realisiert, daß es dir lediglich "um das Einlesen von Daten aus einer Textdatei in die Datenbank" geht.

Bulk Insert bedeutet nichts anderes, als die Daten in einem Rutsch einzulesen. Das kannst du z.B. auch mit IbExpert machen, wenn du aus den Quelldaten zuvor eine entsprechende SQL-Datei erzeugst.

MeineListe[i] := "insert into Fremdworttabelle (Fremdwort, Beschreibung) values (' + QuotedStr(Fremdwort) + ',' + QuotedStr(Beschreibung) + '); Und am Ende vor dem Freigeben der Liste:
MeineListe.SaveToFile(Datei + '.sql'); Am Ende hast du eine Textdatei, die du direkt in IbExpert via Sql-Script einlesen kannst.

Kurz: Es gibt viele Wege, um diese Daten in die Datenbank zu bekommen. Einen davon hab ich dir gezeigt.

Im Rahmen meiner Recherche habe ich irgendwo gelesen, daß die Orignale Textdatei(mit fixer Datensatzlänge) sozusagen als Block in die ExterneFirebirdTabelle übernommen wird. Daraufhin wird diese ExterneFirebirdTabelle in eine interne Tabelle verwandelt und die externe gelöscht.
Kurz gesagt es ist ein schnellerer Datenimport als das Einlesen jedes einzelnen Datensatzes per Insert...value...
Kannst du mir diese Quelle zeigen, in der beschrieben wird, wie man eine reine Textdatei ohne SQL-Befehle in die Datenbank einliest? Davon hab ich bis heute nämlich noch nie was gehört oder gelesen. Mit External Table hat das, soweit ich das beurteilen kann, aber erstmal nichts zu tun.

Könntest du vielleicht noch mitteilen, wieviele Datensätze insgesamt eingelesen werden sollen? Wenn es wirklich nur ein paar (tausend) sind, dann ist Bulk Insert quasi überdimensioniert. Meine oben gezeigte Methode würde dann vollkommen ausreichen. Bulk Insert hat zudem den Nachteil, daß du nicht ohne weiteres prüfen kannst, ob ein entsprechender Datensatz bereits existiert.
  Mit Zitat antworten Zitat
blutigerAnfänger

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

AW: Einfügen über externalTabelle funktioniert nicht richtig

  Alt 27. Feb 2014, 21:50
@Perlsau
Also ich kann dir leider keine Quelle zeigen, dennoch bin ich mir sicher ähnliches gelesen zu haben.(Altersstarrsinn??)
Ansonsten habe ich ja jetzt Material für ein paar Tage. Gute Nacht.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.655 Beiträge
 
Delphi 12 Athens
 
#5

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
 
#6

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
 
#7

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
 
#8

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
Antwort Antwort


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 02:34 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 by Thomas Breitkreuz