Importar ficheiro CSV para o SQL Server

Estou procurando ajuda para importar um arquivo .csv para o SQL Server utilizando BULK INSERT e tenho algumas perguntas básicas.

Issues:

  1. Os dados do arquivo CSV podem ter , (vírgula) no meio (Ex: descrição), então como eu posso fazer a importação manuseando esses dados?

  2. Se o cliente cria o CSV a partir do Excel, então os dados que têm vírgula são incluídos dentro de "" (aspas duplas) [como o exemplo abaixo], então como a importação pode lidar com isso?

  3. Como rastreamos se algumas filas têm dados ruins, quais saltos de importação? (as linhas de saltos de importação que não são importáveis)

Aqui está a amostra do CSV com cabeçalho:

Name,Class,Subject,ExamDate,Mark,Description
Prabhat,4,Math,2/10/2013,25,Test data for prabhat.
Murari,5,Science,2/11/2013,24,"Test data for his's test, where we can test 2nd ROW, Test."
sanjay,4,Science,,25,Test Only.

E instrução SQL a importar:

BULK INSERT SchoolsTemp
FROM 'C:\CSVData\Schools.csv'
WITH
(
    FIRSTROW = 2,
    FIELDTERMINATOR = ',',  --CSV field delimiter
    ROWTERMINATOR = '\n',   --Use to shift the control to next row
    TABLOCK
)
Solução

Importação SQL Server CSV Baseada

  1. Os dados do arquivo CSV podem ter , (vírgula) no meio (Ex: descrição), então como posso fazer a importação manuseando esses dados?

**Solução***

Se você're utiliza , (vírgula) como um delimitador, então não há como diferenciar entre uma vírgula como terminador de campo e uma vírgula nos seus dados. Eu utilizaria um FIELDTERMINADOR diferente como |||. O código ficaria parecido e isto lidaria perfeitamente com vírgula e uma única barra.

  1. Se o cliente criar o csv a partir do excel, então os dados que têm as vírgulas estão dentro de " ... " (aspas duplas) [como as abaixo exemplo] então como é que a importação pode lidar com isto?

**Solução***

Se você'estiver usando a inserção BULK, então não há como lidar com aspas duplas, os dados serão inseridas com aspas duplas nas linhas. Depois de inserir os dados na tabela você poderia substituir essas aspas duplas por '` `'.

update table
set columnhavingdoublequotes = replace(columnhavingdoublequotes,'"','')
  1. Como rastreamos se algumas linhas têm dados ruins, quais saltos de importação? (as linhas de saltos de importação que não são importáveis)?

**Solução***

Para lidar com linhas que são't carregadas na tabela por causa de dados ou formato inválidos, poderia ser handle usando ERRORFILE property, especifique o nome do arquivo de erro, ele irá escrever as linhas ter erro no arquivo de erro. código deve ser parecido.

BULK INSERT SchoolsTemp
    FROM 'C:\CSVData\Schools.csv'
    WITH
    (
    FIRSTROW = 2,
    FIELDTERMINATOR = ',',  --CSV field delimiter
    ROWTERMINATOR = '\n',   --Use to shift the control to next row
    ERRORFILE = 'C:\CSVDATA\SchoolsErrorRows.csv',
    TABLOCK
    )
Comentários (5)

A melhor, mais rápida e mais fácil maneira de resolver o problema da vírgula nos dados é usar o Excel para salvar um arquivo separado por vírgula após ter configurado o Windows' configuração do separador de lista para algo diferente de uma vírgula (como um pipe). Isto irá então gerar um arquivo separado por pipe (ou qualquer outro) para você que você pode então importar. Isto é descrito aqui.

Comentários (0)

Primeiro você precisa importar o arquivo CSV para a Tabela de Dados

Então você pode inserir linhas em massa usando 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);
                }
            }
        }
    }
}
Comentários (1)