Laden...

Wie kann ich eine 500 MB Datei, kein CSV, mit Bulk Insert importieren

Erstellt von Cornflake vor 9 Jahren Letzter Beitrag vor 9 Jahren 4.479 Views
C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 9 Jahren
Wie kann ich eine 500 MB Datei, kein CSV, mit Bulk Insert importieren

verwendetes Datenbanksystem: MS SQL 2008

Hallo

Vllt hat von euch jemand so ein Problem schon gehabt.
Ich habe eine Datei mit ungefähr folgendem Aufbau.


Spalte1______ Spalte2_______________________________ Spalte3__ Spalte4 Spalte5____
1234567890123 H;LLO WELT H;LLO WELT HALLO WELT           88,88   88888 HALLO WELT
1234567890123 HALLO WELT H;LLO WELT H,LLO WELT           88,88   88888 HALLO WELT
1234567890123 H,LLO WELT HALLO WELT H;LLO WELT           88,88   88888 HALLO WELT
1234567890123 HALLO WELT HALLO WELT HALLO                88,88   88888 HALLO WELT
1234567890123 HALLO WELT HALLO WELT       WELT           88,88   88888 HALLO WELT
1234567890123 HALLO WELT HALLO      HALLO WELT           88,88   88888 HALLO WELT
1234567890123 HALLO WELT       WELT HALLO WELT           88,88   88888 HALLO WELT
 

Diese möchte ich per Bulk insert in eine Datenbank importieren.

Aktuell habe ich folgendes vor:


//Quelle wäre eine DataTable in der alles passend enthalten ist

SqlBulkCopy bcpy = new SqlBulkCopy(mssqlConnection);

bcpy.WriteToServer(Quelle);

Mein Problem liegt eigentlich schon etwas weiter davor, die Datei erstmal in die DataTable zu bekommen und dann soll das möglichst innerhalb von einigen Sekunden passieren.

Wisst ihr einen Weg, wie so eine 500 MB Datei relativ schnell in eine DB importiert werden kann?
Die DB könnte auch lokal auf dem Rechner als Express Version installiert werden.

Grüße Cornflake

F
10.010 Beiträge seit 2004
vor 9 Jahren
  1. Nur weil die Datei keine Seperatoren hat, bedeutet das nicht das sie nicht als CSV anzusehen ist. In deienm Fall ist sie mit festen Spaltengrössen.

  2. Die Daten erst in eine dataTable zu schreiben ist suboptimal.

  3. Und damit benutzt du etwas wie A Fast CSV Reader

16.835 Beiträge seit 2008
vor 9 Jahren

Auf einen Rutsch evtl gar nicht. Dafuer wird der RAM nicht ausreichen.
Nimm immer 1000Zeilen und bulk jeweils diese.
Wird nicht arg viel laenger brauchen aber Ressourcen-schonender.
Bringt ja auch nichts wenns einem um die Ohren fliegt.

W
872 Beiträge seit 2005
vor 9 Jahren

Wahrscheinlich wirst Du am schnellsten mit Transact-SQL Bulk Insert sein...sollte an sich nur etwas Fleißarbeit sein.
Du musst halt ein Format-File mit Deinem Layout erzeugen.

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 9 Jahren

Thx für euere Antworten.

ja den Bulk Insert versuche ich auszuprobieren.
Leider kann der nur Dateien mit Trennzeichen einlesen.
Werde daher die Datei vorher nach einem Regelset selber mit Trennzeichen versehen (500 MB einlesen, bei jedem Spaltenwechsel ein Trennzeichen einfügen, 500 MB schreiben). Dann mit bcp oder bulk Insert in DB einlesen.
Leider konnte ich bisher nichts finden wie das trotz Format Vorgabetabellen geht, eine Datei ohne Trennzeichen einzulesen 🙁

5.658 Beiträge seit 2006
vor 9 Jahren

Leider konnte ich bisher nichts finden wie das trotz Format Vorgabetabellen geht, eine Datei ohne Trennzeichen einzulesen 😦

Du musst halt ein Format-File mit Deinem Layout erzeugen.

Bitte beachte [Hinweis] Wie poste ich richtig?, besonders Punkt 1, 4 und 8.

Christian

Weeks of programming can save you hours of planning

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 9 Jahren

Was habe ich da falsch gepostet?

Weismat schreibt ich soll ein Format-File erzeugen und stellt dazu einen Link rein.

Wie in Punkt 1 angegeben habe ich u.a. hier Bulk insert nachgeschaut. Da steht nur etwas von Trennzeichenunterstützung. So ein Wort wie "fix position" kommt nicht vor, daher feste Positionen scheinen dort nicht angegeben werden zu können.

Wie unter Punkt 4 frage ich ja nach keiner komplett Lösung, nur gibts anscheinend da **gar keine **Lösung zu, daher die Angabe meines zukünftigen Vorgehen eine festbreiten Tabelle mit Trennzeichen vorher zu unterteilen.

Wie unter Punkt 8 angegeben habe ich den Link gelesen, aber dort steht nur wie es mit Trennzeichen geht, welches ja bei mir nicht vorhanden ist.

Evtl. war meine Ausdrucksweise mit "Format Vorgabetabellen" etwas unglücklich. Damit meinte ich eben dieses "Format-File".

4.939 Beiträge seit 2008
vor 9 Jahren

Doch, Bulk Insert unterstützt mittels des Format-File auch feste Spaltenbreiten, s. z.B. Loading Fixed Width files with BCP / Bulk Insert (Stichwort: "CharFixed")

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 9 Jahren

Hi
Danke Th69 🙂
Also meines erarchtens ist die MSDN Doku in diesem Punkt schlecht geschrieben. Da finde ich keinen Punkt in dem beschrieben wird, wie das mit festen Längen genau klappen soll.

Dank deines Links, hege ich jetzt wieder Hoffnung den Part ohne Umbau zum Laufen zu bekommen.
Für alle die da auch in der Klemme sitzen.

Aktuell habe ich folgenden bcp Aufruf:


C:\...\Binn>bcp tests.dbo.Foo in "C:\...\Bar.dat" -f "C:\...\Bar.fmt" -S MyServer\MyDB -T

Die Bar.fmt hat aktuell folgenden Aufbau:


10.0
5
1       SQLINT        0       14      ""       1     S1                          Latin1_General_CI_AS
2       SQLNCHAR      0       39      ""       2     S2                          Latin1_General_CI_AS
3       SQLFLT8       0       10      ""       3     S3                          Latin1_General_CI_AS
4       SQLNCHAR      0       8       ""       4     S4                          Latin1_General_CI_AS
5       SQLNCHAR      0       10      "\r\n"   5     S5                          Latin1_General_CI_AS

Leider bekomme ich aktuell noch ne Fehlermeldung in der Form von:


Kopiervorgang wird gestartet...
SQLState = S1000, NativeError = 0
Error = [Microsoft][SQL Server Native Client 10.0]Unerwartetes EOF in BCP-Datend
atei

0 Zeilen kopiert.
Netzwerkpaketgröße (Bytes): 4096
Zeit (ms.) gesamt: 1123

Falls dazu jemand noch ne Idee hat, wäre super.
Vmtl. muss ich da aber nur nochn bisserl an den Längen rumspielen.

Für die SQLFLT8 Angaben, dazu steht unter SQL Datentypen etwas.
Weitere Links lassen sich gut in Google mit "bulk insert fixed length fields" oder "bulk insert fixed width file sql server" finden.

Ansonsten wäre das jetzt mal die Lösung zur obigen Frage 🙂

Grüße Cornflake

M
171 Beiträge seit 2012
vor 9 Jahren

Mal blöd gefragt, kannst Du das nicht als normale CSV-Datei interpretieren mit Leerzeichen als Trenner und die leeren Einträge rauswerfen?

W
955 Beiträge seit 2010
vor 9 Jahren

Mal blöd gefragt, kannst Du das nicht als normale CSV-Datei interpretieren mit Leerzeichen als Trenner und die leeren Einträge rauswerfen?

Und wie soll er dann Spalte 2 und 5 korrekt zuordnen können?

13 Beiträge seit 2007
vor 9 Jahren

Hi,

schau dir mal dieses Tutorial an http://johnnycode.com/2013/08/19/using-c-sharp-sqlbulkcopy-to-import-csv-data-sql-server/.

Der TextFieldParser kann auch mit festen Feldlängen umgehen ...


textFieldParser.TextFieldType = FieldType.FixedWidth;
textFieldParser.FieldWidths = (4,5,8,2,10);

Gruß Ulf

"Lernen ist nicht angenehm, lernen tut weh." - Aristoteles
M
171 Beiträge seit 2012
vor 9 Jahren

Mal blöd gefragt, kannst Du das nicht als normale CSV-Datei interpretieren mit Leerzeichen als Trenner und die leeren Einträge rauswerfen?
Und wie soll er dann Spalte 2 und 5 korrekt zuordnen können?

Na, die Datei hat doch ein festes Format, da ist es doch kein Problem zu wissen, nach wie vielen Einträgen Spalte X aufhört und Spalte X+1 anfängt. Beispiel, erster numerischer Eintrag ist Spalte 1, zweiter numerischer Eintrag ist Spalte 3, alles dazwischen ist Spalte 2 usw.

W
955 Beiträge seit 2010
vor 9 Jahren

Und was ist wenn in Spalte 2

HALLO 88.88 HALLO

steht? Ist 88.88 schon Spalte 3? Die Werte müssen eindeutig zuordbar sein.

W
872 Beiträge seit 2005
vor 9 Jahren

Ich gebe Cornflake recht, daß MSDN etwas sperrig beschrieben ist.
Folgendes Aussage ist schon witzig in meinem Link

Format files are typically created by using the bcp utility and modified with a text editor as needed. For more information, see bcp Utility. .
Da Du uns ja nur schematische Beispiele gibst, macht es keinen Sinn, das zu lösen - der Teufel bei den Textdateien und Deiner Tabellendefinition steckt im Detail und hier kannst Du kaum 500 MB Daten posten.