Je cherche de l'aide pour importer un fichier .csv
dans le serveur SQL en utilisant BULK INSERT
et j'ai quelques questions de base.
Problèmes:
Les données du fichier CSV peuvent avoir ,
(virgule) entre elles (Ex : description), alors comment puis-je faire l'importation en traitant ces données ?
Si le client crée le CSV à partir d'Excel, les données qui contiennent des virgules sont placées entre " ""` " (guillemets doubles) [comme dans l'exemple ci-dessous], comment l'importation peut-elle gérer cela ?
Comment pouvons-nous savoir si certaines lignes contiennent des données erronées, que l'import ignore ? (l'importation saute-t-elle les lignes qui ne sont pas importables ?)
Voici l'exemple de CSV avec l'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 l'instruction SQL pour 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
)
Importation CSV basée sur SQL Server
,
(virgule) entre elles (Ex :description), alors comment puis-je faire l'importation en traitant ces données ?
Solution
Si vous utilisez ,
(virgule) comme délimiteur, alors 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 FIELDTERMINATOR
comme ||
. Le code devrait ressembler à ceci : il gérera parfaitement les virgules et les slashs simples.
virgule sont placées entre
" ; ... "
(guillemets doubles) [comme dans l'exemple ci-dessous]. exemple], comment l'importation peut-elle gérer cela ?
Solution
Si vous utilisez l'insertion en masse, il n'y a aucun moyen de gérer les guillemets. données seront insérées avec des guillemets dans les lignes. Après avoir inséré les données dans la table, vous pouvez remplacer ces guillemets par '``' ;.
update table
set columnhavingdoublequotes = replace(columnhavingdoublequotes,'"','')
- Comment savoir si certaines lignes contiennent des données erronées et si l'importation les ignore ? (est-ce que l'importation saute 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 invalide, on pourrait gérer en utilisant la propriété [ERRORFILE][1], en spécifiant le nom du fichier d'erreur, les lignes ayant une erreur seront écrites dans le fichier d'erreur. d'erreur dans le fichier d'erreur. Le code devrait ressembler à ceci.
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
)
La meilleure façon, la plus rapide et la plus simple, de résoudre le problème des virgules dans les données est d'utiliser Excel pour enregistrer un fichier séparé par des virgules après avoir réglé le paramètre de séparateur de liste de Windows sur autre chose qu'une virgule (comme un tube). Cela générera alors un fichier séparé par un pipe (ou autre) que vous pourrez ensuite importer. Cette méthode est décrite [ici][1].
Vous devez d'abord importer le fichier CSV dans le tableau des données.
Ensuite, vous pouvez insérer des lignes en vrac en utilisant 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);
}
}
}
}
}