2008-09-18 11 views
23

Potrzebuję zaimportować duży plik CSV do serwera SQL. Używam tego:SQL Bulk import z CSV

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

problemem jest to, wszystkie moje pola są w cudzysłowie (”„), więc rząd faktycznie wygląda:

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

mogę jakoś większość importu nich i powiedzieć do SQL użyć cudzysłowy jako ograniczników pól?

Edit: Problem z użyciem „”, „” jako separatora, jak w przykładach sugerowane jest, że: Co zrobić większość przykładów jest ich importować dane w tym pierwszym”w pierwszej kolumnie, a ostatni "w ostatniej kolejności, potem idą naprzód i usuwają to. Niestety moja pierwsza (i ostatnia) kolumna są datetime i nie pozwalają na "importowanie 20080902 jako datetime."

Z tego, co czytałem dookoła, myślę, że FORMATFILE jest drogą do zrobienia, ale dokumentacja (w tym MSDN) jest strasznie unhelpfull.

+0

Należy ponownie tag ten sqlserver, dzięki czemu wiemy, z której bazy danych korzystasz. – JasonS

Odpowiedz

3

Wiem, że to nie jest prawdziwe rozwiązanie, ale do importowania używam obojętnej tabeli z zestawem nvarchar dla wszystkiego. Następnie robię wstawkę, która usuwa "znaki i wykonuje konwersje" Nie jest ładna, ale wykonuje swoją pracę:

+6

Jak podzielić pola kiedy może być przecinek między cytatami? –

13

Spróbuj FIELDTERMINATOR='","'

Oto wielki link do pomocy przy pierwszym i ostatnim cytatem ... wyglądają jak zwykł podciąg SP

http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file

+0

Nie zadziała :-(. Pierwszym polem w tabeli jest datetime i zaimportuje wiodącą wycenę ("), generując błąd – Radu094

+1

Należy również uważać na aplikacje eksportujące CSV z cytowanymi ciągami, ale numery nie cytowane. – finnw

+1

Pracowałem także dla mnie Używam pliku w formacie xml, więc zamiast FIELDTERMINATOR użyto atrybutu Terminator, a na mojej ostatniej kolumnie użyłem następującego TERMINATORA = '' \ r \ n ' –

1

Lubisz trzeba to zrobić programowo, czy jest to jednorazowy strzał?

Za pomocą narzędzia Enterprise Manager kliknij prawym przyciskiem myszy opcję Importuj dane, aby wybrać separator.

4

Wypróbuj OpenRowSet. Można to wykorzystać do importowania plików Excel. Program Excel może otwierać pliki CSV, więc trzeba tylko znaleźć poprawne [ConnectionString] [2].

[2]: Sterownik = {Sterownik tekstowy Microsoft (* .txt; * .csv)}; Dbq = c: \ txtFilesFolder \; Rozszerzenia = asc, csv, tab, txt;

0

Można również użyć DTS lub SSIS.

1

Musisz uważać, używając BCP/BULK INSERT, ponieważ ani BSP, ani Bulk Insert nie radzą sobie z tym dobrze, jeśli cytowanie nie jest spójne, nawet z plikami formatu (nawet pliki w formacie XML nie oferują tej opcji) i manekinem [" ] znaki na początku i na końcu i użycie [","] jako separatora, ale pliki CSV nie muszą mieć ["] znaków, jeśli nie ma osadzonych znaków [,]. -delimited pliki są czasami nazywane plikami komediowymi.

OpenRowSet będzie wymagać programu Excel na serwerze i może być problematyczny w środowiskach 64-bitowych - wiem, że jest to problematyczne przy użyciu programu Excel in Jet w wersji 64-bitowej.

SSIS jest najlepszym rozwiązaniem, jeśli plik może się różnić od oczekiwań w przyszłości.

0

Czy masz kontrolę nad formatem wejściowym? | (rury) i \ t zwykle powodują lepsze terminatory pól.

0

Jeśli wymyślisz, jak spakować plik do DataTable, proponuję Klasa SqlBulkInsert do wkładania go do SQL Server

1

u można próbować ten kod, który jest bardzo słodki, jeśli chcesz, to usunie niechciane średników z kodu jeśli na przykład dane jest tak:..
„Kelly” , "Reynold", "[email protected]"

Bulk insert test1 
from 'c:\1.txt' with ( 
    fieldterminator ='","' 
    ,rowterminator='\n') 

update test1<br> 
set name =Substring (name , 2,len(name)) 
where name like **' "% '** 

update test1 
set email=substring(email, 1,len(email)-1) 
where email like **' %" '** 
9

Innym hackem, którego czasami używam, jest otwarcie pliku CSV w programie Excel, a następnie napisanie instrukcji sql w komórce na końcu każdego wiersza. Na przykład:

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

Wypełnienie-down może zapełnić to pod każdym rzędzie dla Ciebie. Następnie po prostu skopiuj i wklej dane wyjściowe do nowego okna zapytania.

To stara szkoła, ale jeśli potrzebujesz importować tylko raz na jakiś czas, oszczędzasz sobie, czytając całą ukrytą dokumentację na "właściwy" sposób.

+0

Dobra wskazówka, @jorgeburgos – karlgrz

+0

Dobra rada, dziękuję! – DanB

+1

Wiem, że ta odpowiedź jest starożytna, ale właśnie dostałem się tutaj z wyszukiwarką Google na coś podobnego. To jest wspaniały czas, który chcesz wygenerować dowolny kod z danych tabelarycznych, a nie tylko kod do wczytania instrukcji SQL. Możesz umieścić szablon gdzieś w pliku Excel, następnie wykonaj '= SUBSTITUTE ($ Z $ 999," placeholder_a "," '"& SUBSTITUTE (A2," "", "" "" & "" ")," placeholder_b ", SUBSTITUTE (B2, "" "," "" "))'. Zakładając, że masz szablon w $ Z 999 USD. –

2

Id powiedzieć użytku FileHelpers działalność open source biblioteki

1

Firs trzeba zaimportować plik CSV do tabeli danych

Następnie można wstawić masowych wiersze używając SQLBulkCopy

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); 
       } 
      } 
     } 
    } 
}