SQL-Massenimport aus CSV

Ich muss eine große CSV-Datei in einenSQL-serverimportieren. Ich benutze das:

BULK 
INSERT CSVTest
        FROM 'c:\csvfile.txt'
            WITH
    (
                FIELDTERMINATOR = ',',
                ROWTERMINATOR = '\n'
    )
GO

Problem ist, dass alle meine Felder von Anführungszeichen umgeben sind (""), so dass eine Zeile tatsächlich wie folgt aussieht:

"1","","2","","sometimes with comma , inside", "" 

Kann ich sie irgendwie in großen Mengen importieren und SQL anweisen, die Anführungszeichen als Feldtrennzeichen zu verwenden?

Edit: The problem with using '","' as delimiter, as in the examples suggested is that : What most examples do, is they import the data including the first " in the first column and the last " in the last, then they go ahead and strip that out. Alas my first (and last) column are datetime and will not allow a "20080902 to be imported as datetime.

Nach dem, was ich gelesen habe, denke ich FORMATFILE ist der Weg zu gehen, aber Dokumentation (einschließlich MSDN) ist schrecklich wenig hilfreich.

0
Sie sollten diesen sqlserver erneut taggen, damit wir wissen, welche Datenbank Sie verwenden.
hinzugefügt der Autor JasonS, Quelle

12 Antworten

Sie müssen mit BCP/BULK INSERT aufpassen, da weder BSP noch Bulk Insert gut damit umgehen, wenn die Quotierung nicht konsistent ist, selbst bei Formatdateien (selbst xml Format Dateien bieten diese Option nicht) und Dummy ["] Zeichen bei der Anfang und Ende und Verwendung von [","] als Trennzeichen Technisch gesehen müssen CSV-Dateien keine ["] Zeichen haben, wenn keine eingebetteten [] Zeichen vorhanden sind

Aus diesem Grund werden durch Komma getrennte Dateien manchmal als comedy-limitierte Dateien bezeichnet.

OpenRowSet benötigt Excel auf dem Server und könnte in 64-Bit-Umgebungen problematisch sein - ich weiß, dass es problematisch ist, Excel in Jet in 64-Bit zu verwenden.

SSIS ist wirklich Ihre beste Wette, wenn die Datei in Zukunft von Ihren Erwartungen abweichen wird.

0
hinzugefügt

Yup, K Richard is right: FIELDTERMINATOR = '","'

Siehe http://www.sqlteam.com/article/using-bulk-einfügen-to-load-a-text-Datei für weitere Informationen.

0
hinzugefügt

Versuchen Sie OpenRowSet . Dies kann verwendet werden, um Excel-Zeug zu importieren. Excel kann CSV-Dateien öffnen, sodass Sie nur den korrekten [ConnectionString] [2] ermitteln müssen.

[2]: Treiber = {Microsoft Texttreiber (* .txt; * .csv)}; Dbq = c: \ txtFilesFolder \; Erweiterungen = asc, csv, tab, txt;

0
hinzugefügt

Ein anderer Hack, den ich manchmal benutze, besteht darin, die CSV in Excel zu öffnen und dann Ihre SQL-Anweisung in eine Zelle am Ende jeder Zeile zu schreiben. Beispielsweise:

=concatenate("insert into myTable (columnA,columnB) values ('",a1,"','",b1,"'")")

Ein Fill-Down kann dies in jeder Zeile für Sie auffüllen. Kopieren Sie dann die Ausgabe und fügen Sie sie in ein neues Abfragefenster ein.

Es ist Old-School, aber wenn Sie nur hin und wieder importieren müssen, können Sie sich damit abfinden, alle obskuren Dokumente auf dem "richtigen" Weg zu lesen.

0
hinzugefügt
Netter Tipp, @jorgeburgos
hinzugefügt der Autor karlgrz, Quelle
Ich weiß, dass diese Antwort alt ist, aber ich bin gerade mit einer Google-Suche für etwas Ähnliches gekommen. Dies ist die beste Zeit, wenn Sie Code aus tabellarischen Daten erzeugen wollen, nicht nur Code, um eine SQL-Anweisung zu laden. Sie können eine Vorlage irgendwo in der Excel-Datei speichern, dann = SUBSTITUTE ($ Z $ 999, "placeholder_a", "'" & SUBSTITUTE (A2, "'", "''") & "'"), "placeholder_b", SUBSTITUTE (B2, "'", "' '")) . Angenommen, Sie haben eine Vorlage in $ Z $ 999.
hinzugefügt der Autor Don 01001100, Quelle
Guter Tipp, danke!
hinzugefügt der Autor DanB, Quelle

Müssen Sie das programmatisch machen oder ist es einmalig?

Wenn Sie den Enterprise Manager verwenden und mit der rechten Maustaste auf Daten importieren klicken, können Sie Ihr Trennzeichen auswählen.

0
hinzugefügt

Wenn Sie herausfinden, wie die geparste Datei in eine DataTable umgewandelt wird, würde ich die SqlBulkInsert-Klasse zum Einfügen in SQL Server vorschlagen.

0
hinzugefügt

Sie können auch DTS oder SSIS verwenden.

0
hinzugefügt

Try FIELDTERMINATOR='","'

Hier ist ein großartiger Link, um mit dem ersten und letzten Zitat zu helfen ... schau, wie er den Teilstring SP benutzt hat

http://www.sqlteam.com/article/using-bulk-einfügen-zu-laden-eine-Text-Datei

0
hinzugefügt
Arbeitete auch für mich. Ich verwende eine XML-Format-Datei, so dass das Terminator-Attribut anstelle von FIELDTERMINATOR verwendet wurde. Außerdem habe ich in meiner letzten Spalte folgendes verwendet: TERMINATOR = '"\ r \ n'
hinzugefügt der Autor Craig McKeachie, Quelle
Es wird nicht funktionieren :-(. Das erste Feld in der Tabelle ist eine Datetime und es wird das führende Zitat (") damit importiert, was einen Fehler erzeugt
hinzugefügt der Autor Radu094, Quelle
Passen Sie auch auf Anwendungen auf, die CSV-Dateien mit zitierten Strings exportieren, aber keine Zahlen enthalten.
hinzugefügt der Autor finnw, Quelle

Haben Sie die Kontrolle über das Eingabeformat? | (Rohre), und machen normalerweise bessere Feldabbrecher.

0
hinzugefügt

Ich weiß, das ist keine echte Lösung, aber ich verwende eine Dummy-Tabelle für den Import mit Nvarchar für alles eingestellt. Dann mache ich eine Einfügung, die die "Zeichen" löscht und die Konvertierungen durchführt. Es ist nicht schön, aber es macht den Job.

0
hinzugefügt
Wie teilen Sie die Felder auf, wenn zwischen den Anführungszeichen Kommas stehen?
hinzugefügt der Autor Jeremy Stein, Quelle

Ich würde sagen, FileHelpers ist eine Open-Source-Bibliothek

0
hinzugefügt

Zunächst müssen Sie eine CSV-Datei in Datentabelle importieren

Dann können Sie Massenzeilen mit SQLBulkCopy einfügen

using System;
using System.Data;
using System.Data.SqlClient;

namespace SqlBulkInsertExample
{
    class Program
    {
      static void Main(string[] args)
        {
            DataTable prodSalesData = new DataTable("ProductSalesData");

           //Create Column 1: SaleDate
            DataColumn dateColumn = new DataColumn();
            dateColumn.DataType = Type.GetType("System.DateTime");
            dateColumn.ColumnName = "SaleDate";

           //Create Column 2: ProductName
            DataColumn productNameColumn = new DataColumn();
            productNameColumn.ColumnName = "ProductName";

           //Create Column 3: TotalSales
            DataColumn totalSalesColumn = new DataColumn();
            totalSalesColumn.DataType = Type.GetType("System.Int32");
            totalSalesColumn.ColumnName = "TotalSales";

           //Add the columns to the ProductSalesData DataTable
            prodSalesData.Columns.Add(dateColumn);
            prodSalesData.Columns.Add(productNameColumn);
            prodSalesData.Columns.Add(totalSalesColumn);

           //Let's populate the datatable with our stats.
           //You can add as many rows as you want here!

           //Create a new row
            DataRow dailyProductSalesRow = prodSalesData.NewRow();
            dailyProductSalesRow["SaleDate"] = DateTime.Now.Date;
            dailyProductSalesRow["ProductName"] = "Nike";
            dailyProductSalesRow["TotalSales"] = 10;

           //Add the row to the ProductSalesData DataTable
            prodSalesData.Rows.Add(dailyProductSalesRow);

           //Copy the DataTable to SQL Server using SqlBulkCopy
            using (SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=dbProduct;Integrated Security=SSPI;Connection Timeout=60;Min Pool Size=2;Max Pool Size=20;"))
            {
                dbConnection.Open();
                using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                {
                    s.DestinationTableName = prodSalesData.TableName;

                    foreach (var column in prodSalesData.Columns)
                        s.ColumnMappings.Add(column.ToString(), column.ToString());

                    s.WriteToServer(prodSalesData);
                }
            }
        }
    }
}
0
hinzugefügt