Domanda

Devo importare un file CSV di grandi dimensioni in un server SQL.Sto usando questo:

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

il problema è che tutti i miei campi sono racchiusi tra virgolette (" "), quindi una riga in realtà assomiglia a:

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

Posso in qualche modo importarli in blocco e dire a SQL di utilizzare le virgolette come delimitatori di campo?

Modificare:Il problema con l'utilizzo di '","' come delimitatore, come negli esempi suggeriti è che:Ciò che fa la maggior parte degli esempi è importare i dati incluso il primo " nella prima colonna e l'ultimo " nell'ultima, quindi procedere e rimuoverli.Purtroppo la mia prima (e ultima) colonna è datetime e non consentirà l'importazione di "20080902 come datetime.

Da quello che ho letto in giro penso che FORMATFILE sia la strada da percorrere, ma la documentazione (incluso MSDN) è terribilmente inutile.

È stato utile?

Soluzione

So che questa non è una soluzione reale, ma utilizzo una tabella fittizia per l'importazione con nvarchar impostato per tutto.Quindi eseguo un inserto che rimuove i caratteri " ed esegue le conversioni.Non è carino ma fa il suo lavoro.

Altri suggerimenti

Tentativo FIELDTERMINATOR='","'

Ecco un ottimo collegamento per aiutare con la prima e l'ultima citazione... guarda come ha usato la sottostringa SP

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

Un altro trucco che utilizzo a volte è aprire il CSV in Excel, quindi scrivere l'istruzione SQL in una cella alla fine di ogni riga.Per esempio:

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

Un riempimento può popolarlo in ogni riga per te.Quindi copia e incolla l'output in una nuova finestra di query.

È vecchia scuola, ma se hai bisogno di importare solo una volta ogni tanto ti risparmia il fastidio di leggere tutta l'oscura documentazione sul modo "corretto" per farlo.

Tentativo OpenRowSet.Questo può essere usato per importare materiale Excel.Excel può aprire file CSV, quindi è sufficiente individuare la [ConnectionString][2] corretta.

[2]:Driver={Driver di testo Microsoft (*.txt;*.csv)};Dbq=c: xtFilesFolder\;Estensioni=asc,csv,tab,txt;

Direi che usa FileHelpers è una libreria open source

È necessario eseguire questa operazione a livello di programmazione o si tratta di un'operazione una tantum?

Utilizzando Enterprise Manager, facendo clic con il pulsante destro del mouse su Importa dati è possibile selezionare il delimitatore.

Devi fare attenzione con BCP/BULK INSERT perché né BSP né Bulk Insert lo gestiscono bene se le virgolette non sono coerenti, anche con i file di formato (anche i file di formato XML non offrono l'opzione) e i caratteri fittizi ["] alla fine inizio e fine e utilizzando [","] come separatore.Tecnicamente non è necessario che i file CSV contengano caratteri ["] se non sono presenti caratteri [,] incorporati

È per questo motivo che i file delimitati da virgole vengono talvolta definiti file con limiti comici.

OpenRowSet richiederà Excel sul server e potrebbe essere problematico in ambienti a 64 bit: so che è problematico utilizzare Excel in Jet a 64 bit.

SSIS è davvero la soluzione migliore se è probabile che il file vari rispetto alle tue aspettative in futuro.

Puoi provare questo codice, che è molto dolce se vuoi, questo rimuoverà i punti e virgola indesiderati dal tuo codice.se ad esempio i tuoi dati sono così:
"Kelly","Reynold","kelly@reynold.com"

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 **' %" '**

Per prima cosa devi importare il file CSV nella tabella dati

Quindi puoi inserire righe in blocco utilizzando 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);
                }
            }
        }
    }
}

Sì, K Richard ha ragione: FIELDTERMINATOR = '","'

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

Potresti anche usare DTS o SSIS.

Hai il controllo sul formato di input?| (Pipes) e di solito creano migliori terminatori di campo.

Se capisci come analizzare il file in un DataTable, suggerirei la classe SqlBulkInsert per inserirlo in SQL Server.

Questa è una vecchia domanda, quindi scrivo questa per aiutare chiunque si imbatta in essa.

SQL Server 2017 introduce il parametro FIELDQUOTE destinato a questo esatto caso d'uso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top