Einzelnen Beitrag anzeigen

Joerginger

Registriert seit: 22. Jan 2009
Ort: Wien
38 Beiträge
 
Delphi 7 Enterprise
 
#1

Grosse Datenmengen in SQL einfügen - Tuning?

  Alt 10. Jun 2013, 18:53
Datenbank: MS-SQL • Version: 2008R2 • Zugriff über: ADO
Hallo liebe DP-Profis,

ich bastel seit geraumer Zeit an einem ZusatzTool zu unserem ERP-System herum, das Daten aus (fixed-length) Text"Dateien" in MS-SQL-Tabellen abbilden soll... Und bis auf kleine Problemchen läufts auch, theoretisch, aber natürlich nicht so performant, wie ich mir das vorstelle. Die Textfiles beinhalten pro Datensatz bis zu 530!!! Felder, und z.B. im Belegstamm haben wir hier derzeit ca. 170.000 Belege, von den Positionen red' ich momentan noch nicht mal (OK, doch, sind 2.67 Millionen). Und da ich mit SQL grad mal erst begonnen habe ists für mich natürlich eher schwierig (ausser mittels viel Recherche hier) mich vorwärtszutasten... (Für die Interessierten: ERP ist BüroWARE, und leider, nein, wir werden's in den nächsten 2 Jahren nicht austauschen...)

Meine Herangehensweise ist bisher, die Variablennamen und damit die Parametervorbereitung nur 1 x zu durchlaufen, und bei jedem gelesenen Datensatz dann nur mehr die Werte in die Parameter einzufügen, ungefähr so:

Zuerst zerlege ich mir den Text-Datensatz in ein Array auf das ich mit der Feldnummer zugreifen kann...
Danach kommt in etwa dies... jaja, nicht der sauberste Code aber ich steh' da ja noch am Anfang... Verzeiht...

Delphi-Quellcode:
for i:=0 to iH (höchste Feldnummer)
begin
  try //wir versuchen, die Felder zuzuweisern
    sVA:=aSQLVals[i].sValue; //Inhalt aus dem Werte-Array holen
    if (sVA<>'') or (regFillAll) then //Wenns gefüllt ist oder alle Felder geschrieben werden sollen, hier ist regFillAll False...
        DBqu.Parameters.ParamByName(aBWVars[i].sNum).Value:=sVA; //Wert in die Parameterliste
  except //sofern es Peng gemacht hat ;-)
     ... Errorhandling
  end;
end;
Danach findet die eigentliche Schreiberei statt, also myQuery.ExecSQL;

Daraus ergibt sich leider folgendes Problem:
Entweder schreibe ich ALLE Werte (also auch leere Felder) brav in jedes einzelne Feld in dem aktuellen Datensatz - das ist allerdings grottig langsam
oder ich schreibe (wie in diesem Beispiel) nur dann, wenn wirklich im Feld was drinsteht - dann bleibt - wenn nicht drübergeschrieben wird - der Inhalt dieses Feldes vom vorigen Satz hängen und steht im nächsten automatisch auch drin... eher blöd...

Gibt's für solche Anwendungen ein Patentrezept? Eine 'best practice'? Über ca. 10.000 Artikel brauch ich mit diesem Code (und dem Lesen und aufdröseln der Daten und und und) rund 7 Minuten - das wäre zu verkraften - wenn ich NUR die Felder mit Inhalt eintrage. Dann hat's Fehler (also Werte vom vorigen Satz). Wenn ich alle Felder eintrage dauerts dann ca. 40 Minuten
Und die Artikel sind eher noch eine kleinere Tabelle...

Irgendwo glaube ich gelesen zu haben, dass man(n) da irgendwas 'preparen' soll, aber wo und wie?

Oder gäbe es die Möglichkeit (Felder sind fixed length, also Artikelnummer ist immer von Stelle 1 bis 25) das dem SQL sinnvoll per Bulk bzw. external reinzupusten?

Und noch eine Frage: gibts eine Variante nicht alle Werte zu übergeben und dem Delphi / SQL zu erklären, dass er nicht die vom vorigen Satz 'gespeichert lassen soll'?

I steh momentan am Schlauch

GLG,

ein ratloser Mr. Joerginger
  Mit Zitat antworten Zitat