Importer un fichier CSV dans SQL Server


193

Je recherche de l'aide pour importer un .csvfichier dans SQL Server en utilisant BULK INSERTet j'ai quelques questions de base.

Problèmes:

  1. Les données du fichier CSV peuvent avoir ,(virgule) entre (Ex: description), alors comment puis-je effectuer une importation en gérant ces données?

  2. Si le client crée le CSV à partir d'Excel, les données contenant des virgules sont placées entre ""(guillemets) [comme l'exemple ci-dessous]. Comment l'importation peut-elle gérer cela?

  3. Comment pouvons-nous savoir si certaines lignes contiennent des données incorrectes, quelles importations ignorent? (importe-t-il les lignes qui ne sont pas importables)

Voici l'exemple CSV avec en-tête:

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.

Et instruction SQL à importer:

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
)

Peut-être SSMS: Comment importer (copier / coller) des données d'Excel peut aider (si vous ne voulez pas utiliser BULK NSERTou n'avez pas les autorisations pour cela).
Denis

Réponses:


174

Importation CSV SQL Server basée

1) Les données du fichier CSV peuvent avoir ,(virgule) entre (Ex: description), alors comment puis-je effectuer une importation en gérant ces données?

Solution

Si vous utilisez ,(virgule) comme délimiteur, il n'y a aucun moyen de faire la différence entre une virgule comme terminateur de champ et une virgule dans vos données. J'utiliserais un autre FIELDTERMINATORcomme ||. Le code ressemblerait à ce qui gérera parfaitement la virgule et la barre oblique simple.

2) Si le client crée le csv à partir d'Excel, les données contenant des virgules sont placées entre " ... "(guillemets) [comme l'exemple ci-dessous], comment l'importation peut-elle gérer cela?

Solution

Si vous utilisez l'insertion BULK, il n'y a aucun moyen de gérer les guillemets doubles, les données seront insérées avec des guillemets doubles dans les lignes. après avoir inséré les données dans le tableau, vous pouvez remplacer ces guillemets doubles par « ».

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

3) Comment pouvons-nous suivre si certaines lignes ont des données incorrectes, lesquelles importent des sauts? (est-ce que l'importation ignore les lignes qui ne sont pas importables)?

Solution

Pour gérer les lignes qui ne sont pas chargées dans la table en raison de données ou d'un format non valides, peuvent être traitées à l' aide de la propriété ERRORFILE , spécifiez le nom du fichier d'erreur, il écrira les lignes contenant des erreurs dans le fichier d'erreur. le code devrait ressembler à.

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
    )

1
Merci pour l'aide. Reg the Solution # 1: Pouvons-nous créer || fichier de valeurs séparées d'Excel? Parce qu'environ 20% des fichiers sources sont créés à l'aide d'Excel par le client.
Prabhat

@Prabhat Comment vous chargez des fichiers Excel dans SQL Server?
Vishwanath Dalvi

Ce ne sont pas des fichiers Excel que je charge. Le client utilise Excel pour créer des fichiers .CSV (pour 20% des données source importées par notre application). Et je demandais si nous créons des fichiers csv en utilisant Excel comment pouvons-nous avoir || comme séparateur de valeur de colonne?
Prabhat

Si vous avez une influence sur la façon dont le client crée des fichiers CSV à partir d'Excel, vous pouvez leur apprendre à définir le caractère de séparation dans Excel (et bien, ce n'est plus un fichier séparé par une "virgule", il serait séparé par un tube (|), par exemple. Étant donné les obstacles que vous franchissez pour cela, et si vous avez SSIS, je vous recommande de vous y inscrire. Les versions de SQL Server 2012 et ultérieures ont un concepteur SSIS très robuste (également dans VS 2012 et versions ultérieures) qui permettre à votre client de vous envoyer simplement les fichiers Excel au lieu de csv.
qxotk

Je ne suis pas sûr que ce soit tout à fait exact. Vous pouvez traiter les guillemets doubles dans SQL Bulk Insert. Il y a un débordement de pile sur ce sujet et on peut utiliser des fichiers de format pour apprendre à insérer en bloc divers déliminateurs. stackoverflow.com/questions/25726385/... advancesharp.com/blog/1083/...
DtechNet

37

Vous devez d'abord créer une table dans votre base de données dans laquelle vous importerez le fichier CSV. Une fois la table créée, suivez les étapes ci-dessous.

• Connectez-vous à votre base de données à l’aide de SQL Server Management Studio

• Faites un clic droit sur votre base de données et sélectionnez Tasks -> Import Data...

• Cliquez sur le Next >bouton

• Pour la source de données, sélectionnez Flat File Source. Utilisez ensuite le bouton Parcourir pour sélectionner le fichier CSV. Passez un peu de temps à configurer la façon dont vous voulez que les données soient importées avant de cliquer sur le Next >bouton.

• Pour la destination, sélectionnez le fournisseur de base de données approprié (par exemple pour SQL Server 2012, vous pouvez utiliser SQL Server Native Client 11.0). Entrez le nom du serveur. Vérifiez le Use SQL Server Authenticationbouton radio. Entrez le nom d'utilisateur, le mot de passe et la base de données avant de cliquer sur le Next >bouton.

• Dans la fenêtre Sélectionner les tables et vues source, vous pouvez modifier les mappages avant de cliquer sur le Next >bouton.

• Cochez la Run immediatelycase et cliquez sur le Next >bouton.

• Cliquez sur le Finishbouton pour exécuter le package.

Ce qui précède a été trouvé sur ce site Web (je l'ai utilisé et testé):


32
Ce serait bien si vous donniez une attribution à la page où vous avez copié / collé cette réponse ...
SierraOscar

1
Il n'est pas nécessaire de pré-créer la table, elle peut être créée pendant le processus d'importation
bside

1
J'adore le fait que vous venez de copier-coller à partir d'une page Web avec la ligne si utile "Passez du temps à configurer la façon dont vous voulez que les données soient importées" . C'était tout ce que je cherchais: je ne semble pas du tout pouvoir le configurer!
Auspex

Oh, et "Cochez la case d'option Utiliser l'authentification SQL Server" est faux, car vous pouvez très bien vouloir utiliser l'authentification Windows. C'est celui qui fonctionne pour vous.
Auspex

merci trouvé une procédure étape par étape avec des images pour implémenter la procédure ci-dessus, qui vaut le coup d'œil: qawithexperts.com/article/sql
...

23

2) Si le client crée le csv à partir d'Excel, les données contenant des virgules sont placées entre "..." (guillemets doubles) [comme l'exemple ci-dessous] alors comment l'importation peut-elle gérer cela?

Vous devez utiliser les options 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
)

2
Notez que le spécificateur FORMAT n'est disponible que depuis SQL Server 2017.
kristianp

14

Le moyen le meilleur, le plus rapide et le plus simple de résoudre le problème de virgule dans les données consiste à utiliser Excel pour enregistrer un fichier séparé par des virgules après avoir défini le paramètre de séparateur de liste de Windows sur autre chose qu'une virgule (telle qu'un tuyau). Cela générera ensuite un fichier séparé par un tube (ou autre) que vous pourrez ensuite importer. Ceci est décrit ici .


4

Premièrement, vous devez importer un fichier CSV dans la table de données

Ensuite, vous pouvez insérer des lignes en bloc à l'aide de 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);
                }
            }
        }
    }
}

un wrapper peut-être plus convivial autour des classes BulkCopy busybulkcopy.codeplex.com
busytools

3

Voici comment je le résoudrais:

  1. Enregistrez simplement votre fichier CSV en tant que feuille XLS dans Excel (ce faisant, vous n'aurez pas à vous soucier des délimiteurs. Le format de feuille de calcul Excel sera lu comme un tableau et importé directement dans un tableau SQL)

  2. Importer le fichier à l'aide de SSIS

  3. Écrivez un script personnalisé dans le gestionnaire d'importation pour omettre / modifier les données que vous recherchez (ou exécutez un script maître pour examiner les données que vous souhaitez supprimer)

Bonne chance.


3
Downvote: l'importation de fichiers XLS avec SSIS est terrible. SSIS essaiera de deviner les types de données des données Excel, mais peut deviner mal et vous ne pouvez rien y faire. Il vaut mieux utiliser CSV.
NReilingh le

Eh bien, je suggérerais aussi csv, mais si vous aviez lu le scénario de l'OP, il avait des scénarios spéciaux en particulier avec des délimiteurs qui ne sont pas un problème avec les feuilles xls. Généralement, des scénarios de cas spéciaux comme ceux-ci ne nécessitent pas une solution complète, mais un correctif qui préserve les données. Lors du téléchargement du fichier, SSIS vous permet de choisir le mappage de données entre les tables source et de destination, ce qui facilite encore une fois l'effort impliqué. C'est pourquoi cette méthode a été suggérée comme un hack rapide.
Zee

1
SSIS peut déjà gérer les délimiteurs de texte CSV. Si vous utilisez quand même SSIS, me donner la peine de sauvegarder votre CSV en tant que XLS me semble tout d'abord ajouter une casse potentielle sans raison.
NReilingh

De plus, j'ai régulièrement des fichiers CSV trop volumineux pour Excel.
Auspex

3

Comme ils n'utilisent pas l'assistant d'importation SQL, les étapes seraient les suivantes:

entrez la description de l'image ici

  1. Faites un clic droit sur la base de données dans les tâches d' option pour importer des données,

  2. Une fois l'assistant ouvert, nous sélectionnons le type de données à impliquer. Dans ce cas, ce serait le

Source de fichier plat

Nous sélectionnons le fichier CSV, vous pouvez configurer le type de données des tables dans le CSV, mais il est préférable de l'apporter à partir du CSV.

  1. Cliquez sur Suivant et sélectionnez dans la dernière option qui est

Client SQL

En fonction de notre type d'authentification, nous le sélectionnons, une fois que cela est fait, une option très importante vient.

  1. Nous pouvons définir l'id de la table dans le CSV (il est recommandé que les colonnes du CSV soient appelées de la même manière que les champs de la table). Dans l'option Modifier les mappages, nous pouvons voir l'aperçu de chaque table avec la colonne de la feuille de calcul, si nous voulons que l'assistant insère l'ID par défaut, nous laissons l'option décochée.

Activer l'insertion d'identifiant

(généralement pas à partir de 1), à la place, si nous avons une colonne avec l'id dans le CSV, nous sélectionnons l'insertion d'id d'activation, l'étape suivante consiste à mettre fin à l'assistant, nous pouvons examiner les modifications ici.

D'autre part, dans la fenêtre suivante peuvent venir des alertes, ou des avertissements l'idéal est d'ignorer cela, seulement s'ils laissent une erreur est nécessaire de faire attention.

Ce lien contient des images .


1

Je sais que ce n'est pas la solution exacte à la question ci-dessus, mais pour moi, c'était un cauchemar lorsque j'essayais de copier des données d'une base de données située sur un serveur séparé vers mon local.

J'essayais de le faire en exportant d' abord les données du serveur vers CSV/txt, puis en les important dans ma table locale.

Les deux solutions: écrire la requête à importer CSVou utiliser l' assistant d' importation de données SSMS produisait toujours des erreurs (les erreurs étaient très générales, indiquant qu'il y avait un problème d'analyse). Et même si je ne faisais rien de spécial, juste exporter vers CSVet ensuite essayer d' importer CSV vers le local DB, les erreurs étaient toujours là.

J'essayais de regarder la section de cartographie et l'aperçu des données, mais il y avait toujours un gros désordre. Et je sais que le problème principal venait de l'une des tablecolonnes, qui contenait JSONet l' SQLanalyseur traitait cela de manière incorrecte.

Donc finalement, j'ai trouvé une solution différente et je veux la partager au cas où quelqu'un d'autre aurait un problème similaire.


Ce que j'ai fait, c'est que j'ai utilisé l' assistant d'exportation sur le serveur externe.

Voici les étapes pour répéter le même processus:
1) Faites un clic droit sur la base de données et sélectionnezTasks -> Export Data...

2) Lorsque l'assistant s'ouvre, choisissez Suivant et à la place de "Source de données:" choisissez "SQL Server Native Client".

entrez la description de l'image ici

Dans le cas d'un serveur externe, vous devrez probablement choisir "Utiliser l'authentification SQL Server" pour le "Mode d'authentification:".

3) Après avoir appuyé sur Suivant , vous devez sélectionner la Destionation .
Pour cela, sélectionnez à nouveau "SQL Server Native Client".
Cette fois, vous pouvez fournir votre local (ou un autre externe DB) DB.

entrez la description de l'image ici

4) Après avoir cliqué sur le bouton Suivant, vous avez deux options pour copier la table entière de l'un DBà l'autre ou pour écrire la requête pour spécifier les données exactes à copier. Dans mon cas, je n'avais pas besoin de la table entière (elle était trop grande), mais juste d'une partie de celle-ci, j'ai donc choisi «Ecrire une requête pour spécifier les données à transférer».

entrez la description de l'image ici

Je suggérerais d'écrire et de tester la requête sur un éditeur de requête distinct avant de passer à Wizard.

5) Et enfin, vous devez spécifier la table de destination où les données seront sélectionnées.

entrez la description de l'image ici

Je suggère de le laisser sous [dbo].[Query]un Tablenom personnalisé au cas où vous auriez des erreurs lors de l'exportation des données ou si vous n'êtes pas sûr des données et que vous souhaitez les analyser plus avant avant de passer à la table exacte que vous souhaitez.

Et maintenant, allez directement à la fin de l'assistant en appuyant sur les boutons Suivant / Terminer .


0

Importez le fichier dans Excel en ouvrant d'abord excel, puis en accédant à DATA, importez à partir du fichier TXT, choisissez l'extension csv qui conservera 0 valeurs préfixées et enregistrez cette colonne en tant que TEXT car Excel supprimera le 0 de début sinon (NE double-cliquez pas à ouvrir avec Excel si vous avez des données numériques dans un champ commençant par 0 [zéro]). Ensuite, enregistrez simplement sous forme de fichier texte délimité par des tabulations. Lorsque vous importez dans Excel, vous obtenez une option pour enregistrer en tant que GENERAL, TEXT, etc. choisissez TEXT afin que les guillemets au milieu d'une chaîne dans un champ comme YourCompany, LLC soient également préservés ...

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

J'aimerais pouvoir utiliser les fonctionnalités FORMAT et Fieldquote mais cela ne semble pas être pris en charge dans ma version de SSMS


0

Je sais qu'il y a des réponses acceptées mais je veux quand même partager mon scénario qui aidera peut-être quelqu'un à résoudre son problème OUTILS

  • ASP.NET
  • APPROCHE EF CODE-FIRST
  • SSMS
  • EXCELLER

SCÉNARIO Je chargeais l'ensemble de données qui est au format CSV qui devait plus tard être affiché sur la vue J'ai essayé d'utiliser le chargement en bloc mais je ne peux pas charger comme je l' BULK LOADutilisais

FIELDTERMINATOR = ','

et la cellule Excel utilisait également , cependant, je ne pouvais pas non plus utiliser Flat file sourcedirectement parce que j'utilisais Code-First Approachet faisais ce modèle uniquement dans SSMS DB, pas dans le modèle à partir duquel j'ai dû utiliser les propriétés plus tard.

SOLUTION

  1. J'ai utilisé une source de fichier plat et créé une table de base de données à partir d'un fichier CSV ( cliquez avec le bouton droit sur DB dans SSMS -> Importer un fichier plat -> sélectionnez le chemin CSV et effectuez tous les paramètres comme indiqué )
  2. Made Model Class dans Visual Studio (vous DEVEZ GARDER tous les types de données et les noms identiques à ceux du fichier CSV chargé dans SQL)
  3. utiliser Add-Migrationdans la console du package NuGet
  4. Mettre à jour la base de données


0

Toutes les réponses ici fonctionnent très bien si vos données sont «propres» (aucune violation de contrainte de données, etc.) et que vous avez accès à la mise du fichier sur le serveur. Certaines des réponses fournies ici s'arrêtent à la première erreur (violation PK, erreur de perte de données, etc.) et vous donnent une erreur à la fois si vous utilisez la tâche d'importation intégrée de SSMS. Si vous souhaitez rassembler toutes les erreurs en même temps (au cas où vous voudriez dire à la personne qui vous a donné le fichier .csv de nettoyer ses données), je recommande ce qui suit comme réponse. Cette réponse vous donne également une flexibilité totale lorsque vous «écrivez» vous-même le SQL.

Remarque: je vais supposer que vous utilisez un système d'exploitation Windows et que vous avez accès à Excel et SSMS. Sinon, je suis sûr que vous pouvez modifier cette réponse en fonction de vos besoins.

  1. À l'aide d'Excel, ouvrez votre fichier .csv. Dans une colonne vide, vous écrirez une formule qui construira des INSERTdéclarations individuelles comme =CONCATENATE("INSERT INTO dbo.MyTable (FirstName, LastName) VALUES ('", A1, "', '", B1,"')", CHAR(10), "GO")où A1 est une cellule qui a les données de prénom et A2 a les données de nom par exemple.

    • CHAR(10)ajoute un caractère de nouvelle ligne au résultat final et GOnous permettra de l'exécuter INSERTet de passer au suivant même s'il y a des erreurs.
  2. Mettez en surbrillance la cellule avec votre =CONCATENATION()formule

  3. Shift + End pour mettre en évidence la même colonne dans le reste de vos lignes

  4. Dans le ruban> Accueil> Edition> Remplir> Cliquez vers le bas

    • Cela applique la formule tout le long de la feuille afin que vous n'ayez pas à copier-coller, faire glisser, etc. vers le bas potentiellement des milliers de lignes à la main
  5. Ctrl + C pour copier les INSERTinstructions SQL formulées

  6. Coller dans SSMS

  7. Vous remarquerez qu'Excel, probablement de manière inattendue, a ajouté des guillemets doubles autour de chacune de vos commandes INSERTet GO. Il s'agit d'une "fonctionnalité" (?) De copie de valeurs multilignes hors d'Excel. Vous pouvez simplement trouver et remplacer "INSERTet GO"avec INSERTet GOrespectivement pour nettoyer cela.

  8. Enfin, vous êtes prêt à exécuter votre processus d'importation

  9. Une fois le processus terminé, vérifiez la fenêtre Messages pour toute erreur. Vous pouvez sélectionner tout le contenu (Ctrl + A) et copier dans Excel et utiliser un filtre de colonne pour supprimer tous les messages réussis et vous vous retrouvez avec toutes les erreurs.

Ce processus prendra certainement plus de temps que les autres réponses ici, mais si vos données sont «sales» et pleines de violations SQL, vous pouvez au moins rassembler toutes les erreurs en même temps et les envoyer à la personne qui vous a fourni les données, si cela est votre scénario.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.