Re: Textdatei > 500 MB für DB vorbereiten
das #12 ist da immer in einer eigenen Zeile?
(oder maximal am Ende einer Datensatzzeile, also vor einem Zeilenwechsel bzw hinter einem Feldnamen) zwei ganz einfache Beispiele zum Auslesen aller Feldnamen: ! Groß-/Kleinschreibung wird beachtet
Delphi-Quellcode:
var F: TextFile;
Feldnamen: Array of String; S: String; B: Boolean; i: Integer; begin AssignFile(F, {Dateiname}); Reset(F1); Feldnamen := nil; while not EOF(F) do begin ReadLn(F, S); i := Pos(':', S); if i = 0 then Continue; S := Trim(Copy(S, 1, i - 1)); B := True; for i := High(Feldnamen) downto 0 do if Feldnamen[i] = S then B := False; if B then begin i := Length(Feldnamen); SetLength(Feldnamen, i + 1); Feldnamen[i] := S; end; end; CloseFile(F); end;
Delphi-Quellcode:
var F: TextFile;
Feldnamen: TStringList; S: String; i: Integer; begin AssignFile(F, {Dateiname}); Reset(F1); Feldnamen := TStringList.Create; Feldnamen.Duplicates := dupIgnore; while not EOF(F) do begin ReadLn(F, S); i := Pos(':', S); if i = 0 then Continue; S := Trim(Copy(S, 1, i - 1)); Feldnamen.Add(S); end; end; CloseFile(F); end; |
Re: Textdatei > 500 MB für DB vorbereiten
Aber das ist doch popeleinfach...
Delphi-Quellcode:
Die Funktion 'GetNextField' liest die nächste nicht-leere Zeile vom MyTextFile ein und liefert TRUE, wenn es sich um einen Feldinhalt handelt (und dann in 'sFieldName' den Feldnamen und in 'sFieldContents' den Inhalt), oder FALSE sonst.
While not MyTextFile.Eof do begin
MyTable.Append; While GetNextField(MyTextFile, sFieldName, sFieldContents) do MyTable[sFieldName].AsString := sFieldContents MyTable.Post; End; Das Langsame hier ist:
Delphi-Quellcode:
Das bekommt man mit einer kleinen Hashmap wesentlich schneller hin. Diese Map liefert zum Feldnamen den Feldindex, sodaß man dann direkt in die entsprechende Spalte schreiben kann.
MyTable[sFieldName].AsString := sFieldContents
Selbst wenn das Einlesen 30 min dauert, ist das immer noch kürzer, als umständlich nach einer performanten Lösung zu suchen. Was hast Du davon, wenn Du in 5 Tagen eine solche implementiert hast? [edit]... Wenn die Tabelle noch nicht existiert bzw. die Gesamtmenge der Feldnamen noch nicht bekannt ist, würde ich die Datei einmal durchscannen, um alle Feldnamen zu erhalten. Damit wird dann die Tabelle erzeugt bzw. ggf. erweitert. Im laufenden Betrieb geht das nicht so einfach. Du kannst aber auch komplett auf ein TDataset verzichten und nur mit SQL arbeiten. Dazu müsste man aber wissen, ob Access auch DDL kennt, also CREATE / ALTER TABLE, um ggf neue Feldnamen an die Tabelle anzubepseln. [/edit] |
Re: Textdatei > 500 MB für DB vorbereiten
Zitat:
Die Zeile wird durch CRLF abgeschlossen. Der Datensatz wird durch mindestens eine Leerzeile gefolgt von 0x0c in einer extra Zeile vom nächsten Datensatz getrennt. @himitsu: Beide Deiner Routinen sind im Prinzip schnell (auf meinem Testrechner so um die 40 - 50 Sekunden) :thumb: , ABER damit ist das Prog optisch eingefroren. :( Füge ich nun ein Application.ProcessMessage hinzu um z.B. die FilePos oder einen Fortschrittsbalken anzuzeigen, bricht die Performance total zusammen und ich liege in etwa bei der Zeit wie mit meiner kleinen Testroutine. (na ja stimmt nicht ganz, deine ist immer noch deutlich schneller :thumb: ) :( Also werde ich in dieser Richtung mal weitertesten und mich von Streams (mein Ansatz) fernhalten... @alzaimar: Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Textdatei > 500 MB für DB vorbereiten
ich gehe mal davon aus, dass du nicht alle felder abspeichern willst (z. B. SystemABDocUnID: HexID) und wohl auch nicht alle daten, die in dem 1/4 geändert wurden verwerfen.
dann müsstest du dir erst mal aussuchen, welche daten du überhaupt den anwender zeigen willst und in welcher tabellenstruktur du das ablegen möchtest. wenn du das gemacht hast, ist die hauptarbeit eigentlich schon erledigt. du kennst die felder, die tabellen und die namen aus Lotus notes. dann bruchst nur noch einmal durchgehen, wenn der name auftritt entsprechend zuweisen und einmal abspeichern. das geht ruck-zuck. ggf. müsstest du da noch prüfen ob die einträge schon vorhanden sind nach dem schema if not exists then insert else update. das endekennzeichen ist ja #12 und von daher weisst prima wenn 'n neuer datensatz beginnt. schon mal darüber nachgedacht? |
Re: Textdatei > 500 MB für DB vorbereiten
Zitat:
Zitat:
Zitat:
Zitat:
Ein Delta einspielen oder einfach mit dem Gesamtabzug überschreiben. :gruebel: |
Re: Textdatei > 500 MB für DB vorbereiten
der gesamtabzug mit einem vorherigen drop-table ist mit sicherheit schneller. die frage ist nur, ob du das wirklich willst...
ansonsten, sind die benutzerdefinierten felder normal in der lokalen db, nicht in der server db. wie siehts denn aus, woher kommen die daten... und wie sollen sie eingespielt werden... jeder benutzer spielt im quartal das selbe ein? find ich persönlich nicht wirklich sinnvoll. ausserdem trau ich den wenigsten usern zu, dass sie etwas sinnvolles auswählen... wäre es da nicht sinnvoller die daten zentral einzuspielen mit einem superset an daten, die für alle gleich sind und dann die einzelnen user dann die daten zusammenstreichen lassen, welche sie gerne sehen würden? PS: zum einspielen gibt es ja auch mehrere möglichkeiten, z.b. erst mal 'ne tabelle mit 60 oder noch mehr feldern aufmachen, die namen dann zum schluss assigen und die restliche dann zu droppen oder unbenutzt stehen zu lassen, oder einfach alles in 'n blob übernehmen ... ;-) ausserdem, wenn du richtig hingesehen hast, hast du in deinem beispiel flatfile wiederholungszeilen. wie willst mit dennen umgehen ... auch alles 'in 'n blob oder so, dass man danach suchen kann? im zweiten fall, brauchst du 'ne detailtabelle, damit du das ordentlich abhandeln kannst. hoffe solche kleinigkeiten hast nicht übersehen und sind bereites in deinem konzept integriert. |
Re: Textdatei > 500 MB für DB vorbereiten
Zitat:
Zitat:
Hmmm. Du sagst, Du hättest 180.000 Datensätze mit jeweils ca. 20-40 Feldern. Also hmmm, ich denke, das geht in 1-2 Minuten (Feldnamen ermitteln). Was ich daran so dämlich finde, ist jedoch, das die Gesamtmenge der Feldnamen nicht definiert sind. Nun gut. Mal sehen, wenn mir morgen langweilig ist, setz ich mich mal ran. |
Re: Textdatei > 500 MB für DB vorbereiten
Zitat:
Dein TStringDictionary schaue ich mir mal morgen (upps schon so spät) heut nachmittag an. Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Textdatei > 500 MB für DB vorbereiten
Zitat:
was mir schleierhaft ist, was das progy machen soll, wenn der inhalt der db nicht defniert ist... taugt das ja noch nicht mal als adressliste... @alzaimar: was steht dagegen 'ne kontenform zu verwendeten, so wie der textoutput... |
Re: Textdatei > 500 MB für DB vorbereiten
Zitat:
ausserdem müssten natürlich noch entsprechende plausi prüfungen erfolgen. z.b. welche felder unbedingt gefüllt werden müssen und welche leer sein dürfen .. denke, alles in allen, ist das kein ad-hoc projekt. welches in 'ner 1/2 stunde eingeführt ist... da sollt man schon etwas drüber nachdenken, wie man das am sinnvollsten macht. so dass man das dann nicht jedes quartal umschreiben darf ... :angel: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:00 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