Importar arquivo CSV para o SQL Server

186

Estou procurando ajuda para importar um .csvarquivo para o SQL Server usando BULK INSERTe tenho algumas perguntas básicas.

Problemas:

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

  2. Se o cliente cria o CSV a partir do Excel, os dados que possuem vírgula são colocados entre ""(aspas duplas) [como no exemplo abaixo]. Como a importação pode lidar com isso?

  3. Como rastreamos se algumas linhas têm dados incorretos, que a importação ignora? (a importação ignora as linhas que não são importáveis)

Aqui está o exemplo de 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 para 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
)
Prabhat
fonte
Pode ser SSMS: Como importar (Copiar / Colar) dados do Excel pode ajudar (se você não deseja usar BULK NSERTou não tem permissões para isso).
Denis

Respostas:

169

Importação baseada em CSV do SQL Server

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

Solução

Se você estiver usando ,(vírgula) como delimitador, não há como diferenciar uma vírgula como terminador de campo e uma vírgula nos seus dados. Eu usaria um FIELDTERMINATORgosto diferente ||. O código seria semelhante e isso manipulará vírgula e barra única perfeitamente.

2) Se o cliente criar o csv a partir do excel, os dados que possuem vírgula são colocados entre " ... "(aspas duplas) [como o exemplo abaixo]. Então, como a importação pode lidar com isso?

Solução

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

update table
set columnhavingdoublequotes = replace(columnhavingdoublequotes,'"','')

3) Como rastreamos se algumas linhas têm dados incorretos, que a importação ignora? (a importação ignora as linhas que não são importáveis)?

Solução

Para manipular linhas que não são carregadas na tabela devido a dados ou formato inválidos, pode ser manipulado usando a propriedade ERRORFILE , especifique o nome do arquivo de erro, ele gravará as linhas com 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
    )
Vishwanath Dalvi
fonte
1
Obrigado pela ajuda. Regra da solução 1: podemos criar || arquivo de valor separado do Excel? Porque cerca de 20% dos arquivos de origem são criados usando o Excel pelo cliente.
Prabhat
@Prabhat Como você está carregando arquivos do Excel no SQL Server?
Vishwanath Dalvi
Estes não são arquivos do Excel que estou carregando. O cliente está usando o Excel para criar arquivos .CSV (para 20% dos dados de origem que nosso aplicativo importa). E eu estava perguntando se criamos arquivos CSV usando o Excel, como podemos ter || como separador de valor da coluna?
Prabhat
Se você tem influência sobre como o cliente cria arquivos CSV a partir do Excel, pode ensiná-los a definir o caractere separador no Excel (e, bem, ele não é mais um arquivo separado por "vírgula", seria separado por canal (|), Por exemplo, considerando as dificuldades que você está enfrentando para fazer isso, e se você tiver o SSIS - recomendo que você verifique as versões do SQL Server 2012 e posteriores com um designer SSIS muito robusto (também no VS 2012 e posterior) que permitir que seu cliente simplesmente enviar-lhe o excel arquivos em vez de csv.
qxotk
Não tenho certeza se isso é totalmente preciso. Você pode lidar com aspas duplas no SQL Bulk Insert. Há um estouro de pilha neste tópico e pode-se usar arquivos de formato para ensinar vários deliminadores de inserção em massa. stackoverflow.com/questions/25726385/… advancesharp.com/blog/1083/…
DtechNet
33

Você primeiro precisa criar uma tabela em seu banco de dados na qual importará o arquivo CSV. Após a tabela ser criada, siga as etapas abaixo.

• Faça logon no seu banco de dados usando o SQL Server Management Studio

• Clique com o botão direito do mouse no seu banco de dados e selecione Tasks -> Import Data...

• Clique no Next >botão

• Para a fonte de dados, selecione Flat File Source. Em seguida, use o botão Procurar para selecionar o arquivo CSV. Passe algum tempo configurando como deseja que os dados sejam importados antes de clicar no Next >botão.

• Para o destino, selecione o provedor de banco de dados correto (por exemplo, para o SQL Server 2012, você pode usar o SQL Server Native Client 11.0). Digite o nome do servidor. Verifique o Use SQL Server Authenticationbotão de opção. Digite o nome de usuário, senha e banco de dados antes de clicar no Next >botão.

• Na janela Selecionar tabelas e visualizações de origem, você pode editar mapeamentos antes de clicar no Next >botão.

• Marque a Run immediatelycaixa de seleção e clique no Next >botão.

• Clique no Finishbotão para executar o pacote.

O acima foi encontrado neste site (eu o usei e testei):

Zd8n8k
fonte
30
Seria bom se você deu atribuição a página onde você copiar / colar esta resposta a partir de ...
SierraOscar
1
Não é necessário pré-criar a tabela, ele pode ser criado durante o processo de importação
bside
1
Eu amo que você apenas recorte e cole de uma página da web com a linha " tão útil " "Passe algum tempo configurando como deseja que os dados sejam importados" . Era tudo o que eu procurava: parece que não consigo configurá-lo!
Auspex
Ah, e "Verifique o botão de opção Usar autenticação do SQL Server" está errado, pois você pode querer usar a autenticação do Windows. É o que funciona para você.
Auspex
obrigado encontrei um procedimento passo a passo com imagens para implementar o procedimento acima, vale uma olhada: qawithexperts.com/article/sql/…
user3559462
23

2) Se o cliente criar o csv a partir do excel, os dados que tiverem vírgula serão colocados entre "..." (aspas duplas) [como o exemplo abaixo]. Então, como a importação pode lidar com isso?

Você deve usar as opções FORMAT = 'CSV', FIELDQUOTE = '"' ':

BULK INSERT SchoolsTemp
FROM 'C:\CSVData\Schools.csv'
WITH
(
    FORMAT = 'CSV', 
    FIELDQUOTE = '"',
    FIRSTROW = 2,
    FIELDTERMINATOR = ',',  --CSV field delimiter
    ROWTERMINATOR = '\n',   --Use to shift the control to next row
    TABLOCK
)
Oleg
fonte
1
Observe que o especificador FORMAT está disponível apenas desde o SQL Server 2017.
kristianp
13

A maneira melhor, mais rápida e fácil de resolver a vírgula na emissão de dados é usar o Excel para salvar um arquivo separado por vírgula depois de definir a configuração do separador de lista do Windows para algo diferente de vírgula (como um tubo). Isso irá gerar para você um arquivo separado por canal (ou qualquer outro) que você possa importar. Isto é descrito aqui .

Sachin Kainth
fonte
4

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

Em seguida, 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);
                }
            }
        }
    }
}
kombsh
fonte
um invólucro talvez mais user-friendly em torno das aulas BULKCOPY busybulkcopy.codeplex.com
busytools
3

Aqui está como eu resolveria isso:

  1. Apenas salve seu arquivo CSV como uma planilha XLS no Excel (ao fazer isso, você não precisa se preocupar com delimitadores. O formato da planilha do Excel será lido como uma tabela e importado diretamente para uma tabela SQL)

  2. Importar o arquivo usando o SSIS

  3. Escreva um script personalizado no gerenciador de importação para omitir / modificar os dados que você está procurando (ou execute um script mestre para examinar os dados que você deseja remover)

Boa sorte.

Zee
fonte
3
Nota: A importação de arquivos XLS com o SSIS é terrível. O SSIS tentará adivinhar os tipos de dados dos dados do Excel, mas pode adivinhar errado e não há nada que você possa fazer sobre isso. Muito melhor usar CSV.
N
Bem, eu sugiro csv também, mas se você leu o cenário do OP, ele teve alguns cenários especiais, especialmente com delimitadores que não são um problema com as folhas xls. Geralmente, cenários de casos especiais como esses não exigem uma solução extensa, mas uma correção que preserva os dados. Durante o upload do arquivo, o SSIS permite escolher o mapeamento de dados entre as tabelas de origem e destino, o que novamente facilita o esforço envolvido. É por isso que esse método foi sugerido como um hack rápido.
Zee
1
O SSIS já pode manipular delimitadores de texto CSV. Se você estiver usando o SSIS de qualquer maneira, o problema de salvar seu CSV como um XLS primeiro parece-me um acréscimo potencial de quebra sem motivo.
NReilingh
Além disso, rotineiramente tenho arquivos CSV muito grandes para o Excel.
Auspex
3

Como eles não usam o assistente de importação SQL, as etapas seriam as seguintes:

insira a descrição da imagem aqui

  1. Clique com o botão direito do mouse no banco de dados nas tarefas opcionais para importar dados,

  2. Uma vez aberto o assistente , selecionamos o tipo de dados a ser implícito. Nesse caso, seria o

Origem do arquivo simples

Selecionamos o arquivo CSV, você pode configurar o tipo de dados das tabelas no CSV, mas é melhor trazê-lo do CSV.

  1. Clique em Avançar e selecione a última opção que é

Cliente SQL

Dependendo do nosso tipo de autenticação, nós a selecionamos, uma vez que isso é feito, uma opção muito importante é fornecida.

  1. Podemos definir o ID da tabela no CSV (é recomendável que as colunas do CSV sejam chamadas da mesma forma que os campos da tabela). Na opção Editar mapeamentos, podemos ver a visualização de cada tabela com a coluna da planilha; se queremos que o assistente insira o ID por padrão, deixamos a opção desmarcada.

Ativar inserção de ID

(geralmente não começando em 1). Se tivermos uma coluna com o ID no CSV, selecionaremos a inserção de ID de ativação. A próxima etapa é finalizar o assistente. Podemos revisar as alterações aqui.

Por outro lado, na janela a seguir podem aparecer alertas ou avisos, o ideal é ignorar isso, apenas se eles deixarem erro é necessário prestar atenção.

Este link tem imagens .

jarvis24
fonte
0

Importe o arquivo para o Excel primeiro abrindo o excel, depois indo para DATA, importe do arquivo TXT, escolha a extensão csv que preservará 0 valores prefixados e salve a coluna como TEXT, porque o Excel eliminará o 0 principal caso contrário (NÃO clique duas vezes para abrir com o Excel se você tiver dados numéricos em um campo começando com 0 [zero]). Em seguida, salve como um arquivo de texto delimitado por tabulações. Ao importar para o Excel, você tem a opção de salvar como GENERAL, TEXT, etc. escolha TEXT para que as aspas no meio de uma string em um campo como YourCompany, LLC também sejam preservadas ...

BULK INSERT dbo.YourTableName
FROM 'C:\Users\Steve\Downloads\yourfiletoIMPORT.txt'
WITH (
FirstRow = 2, (if skipping a header row)
FIELDTERMINATOR = '\t',
ROWTERMINATOR   = '\n'
)

Gostaria de poder usar a funcionalidade FORMAT e Fieldquote, mas isso não parece ser suportado na minha versão do SSMS

Steve Yo
fonte
0

Sei que há respostas aceitas, mas ainda quero compartilhar meu cenário que talvez ajude alguém a resolver seu problema FERRAMENTAS

  • ASP.NET
  • PRIMEIRA ABORDAGEM DO CÓDIGO EF
  • SSMS
  • EXCEL

CENÁRIO i estava carregando o conjunto de dados no formato CSV, que mais tarde seria mostrado na tela. Tentei usar o carregamento em massa, mas não consigo carregar como BULK LOADestava usando

FIELDTERMINATOR = ','

e a célula do Excel também estava usando , , no entanto, eu também não podia usar Flat file sourcediretamente porque estava usando Code-First Approache fazendo isso apenas no modelo SSMS DB, não no modelo do qual precisei usar as propriedades posteriormente.

SOLUÇÃO

  1. Usei a fonte de arquivo simples e criei a tabela DB a partir do arquivo CSV ( clique com o botão direito do mouse em DB no SSMS -> Importar arquivo simples -> selecione o caminho CSV e faça todas as configurações conforme as instruções )
  2. Classe Model Made no Visual Studio (É necessário manter todos os tipos de dados e nomes iguais aos do arquivo CSV carregado no sql)
  3. usar Add-Migrationno console do pacote NuGet
  4. Atualizar banco de dados
Camaleão
fonte
0

Sei que essa não é a solução exata para a pergunta acima, mas, para mim, foi um pesadelo quando eu estava tentando copiar dados de um banco de dados localizado em um servidor separado para o meu local.

Eu estava tentando fazer isso primeiro exportando dados do servidor para CSV/txte importando -os para minha tabela local.

Ambas as soluções: escrever a consulta para importar CSVou usar o assistente SSMS Import Data estava sempre produzindo erros (os erros eram muito gerais, dizendo que há um problema de análise). E embora eu não estivesse fazendo nada de especial, basta exportar para CSVe depois tentar importar CSV para o local DB, os erros sempre estavam lá.

Eu estava tentando olhar para a seção de mapeamento e a visualização de dados, mas sempre havia uma grande bagunça. E eu sei que o principal problema estava vindo de uma das tablecolunas, que estava contendo JSONe o SQLanalisador estava tratando isso errado.

Então, finalmente, eu vim com uma solução diferente e quero compartilhá-la, caso outra pessoa tenha um problema semelhante.


O que fiz foi usar o Assistente de Exportação no servidor externo.

Aqui estão as etapas para repetir o mesmo processo:
1) Clique com o botão direito do mouse no banco de dados e selecioneTasks -> Export Data...

2) Quando o Assistente for aberto, escolha Avançar e, no lugar de "Fonte de dados:", escolha "SQL Server Native Client".

insira a descrição da imagem aqui

No caso de um servidor externo, você provavelmente terá que escolher "Usar autenticação do SQL Server" para o "Modo de autenticação:".

3) Depois de clicar em Avançar , você deve selecionar o destino .
Para isso, selecione novamente "SQL Server Native Client".
Desta vez, você pode fornecer seu local (ou algum outro externo DB) DB.

insira a descrição da imagem aqui

4) Após pressionar o botão Avançar, você tem duas opções para copiar a tabela inteira de uma DBpara outra ou anotar a consulta para especificar os dados exatos a serem copiados. No meu caso, eu não precisava da tabela inteira (era muito grande), mas apenas de uma parte dela, então escolhi "Escrever uma consulta para especificar os dados a serem transferidos".

insira a descrição da imagem aqui

Sugiro anotar e testar a consulta em um editor de consultas separado antes de passar para o Assistente.

5) E, finalmente, você precisa especificar a tabela de destino onde os dados serão selecionados.

insira a descrição da imagem aqui

Sugiro deixá-lo como [dbo].[Query]ou algum Tablenome personalizado , caso você tenha erros ao exportar os dados ou se não tiver certeza sobre os dados e deseja analisá-los mais detalhadamente antes de passar para a tabela exata desejada.

E agora vá direto para o final do Assistente pressionando os botões Avançar / Concluir .

Arsen Khachaturyan
fonte