咨询区
user3083221
请问在 C# 中是否有好的方式实现将一个大的 csv
导入到 SQL Server 中,这个 csv 文件包含大概 30000
行,25
列。
回答区
Kirk
其实你不需要通过编程的方式,完全可以用 SQL Server 管理器界面
直接将 CSV 导入到 SQL Server 中,如果你真的想要编程实现的话,也不是没有办法,大概步骤如下:
将 CSV 读取到一个 DataTable 中,参考如下代码:
private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
{DataTable csvData = new DataTable();try{using(TextFieldParser csvReader = new TextFieldParser(csv_file_path)){csvReader.SetDelimiters(new string[] { "," });csvReader.HasFieldsEnclosedInQuotes = true;string[] colFields = csvReader.ReadFields();foreach (string column in colFields){DataColumn datecolumn = new DataColumn(column);datecolumn.AllowDBNull = true;csvData.Columns.Add(datecolumn);}while (!csvReader.EndOfData){string[] fieldData = csvReader.ReadFields();//Making empty value as nullfor (int i = 0; i < fieldData.Length; i++){if (fieldData[i] == ""){fieldData[i] = null;}}csvData.Rows.Add(fieldData);}}}catch (Exception ex){return null;}return csvData;}
}
通过 SQLBulkCopy 将 DataTable 插入到 Table 中
对于 Sql Server 的批量插入,绝对首选 SqlBulkCopy
,参考如下代码:
static void InsertDataIntoSQLServerUsingSQLBulkCopy(DataTable csvFileData)
{using(SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=yourDB;Integrated Security=SSPI;")){dbConnection.Open();using (SqlBulkCopy s = new SqlBulkCopy(dbConnection)){s.DestinationTableName = "Your table name";foreach (var column in csvFileData.Columns)s.ColumnMappings.Add(column.ToString(), column.ToString());s.WriteToServer(csvFileData);}
}
Cinchoo
有一个开源工具包:ChoETL (https://www.nuget.org/packages/ChoETL/) 也可以实现通过编程的方式实现批量导入,它是一种流式操作,只需要很少甚至不需要内存,参考如下代码:
string connectionstring = @"#YOUR DB ConnectionString#";
using (SqlBulkCopy bcp = new SqlBulkCopy(connectionstring))
{using (var p = new ChoCSVReader("#YOUR CSV FILE#").WithFirstLineHeader()){bcp.DestinationTableName = "#TABLENAME#";bcp.EnableStreaming = true;bcp.BatchSize = 10000;bcp.BulkCopyTimeout = 0;bcp.NotifyAfter = 100;bcp.SqlRowsCopied += delegate (object sender, SqlRowsCopiedEventArgs e){Console.WriteLine(e.RowsCopied.ToString("#,##0") + " rows copied.");};bcp.WriteToServer(p.AsDataReader());}
}
点评区
在现实开发中,这种需求还是蛮常见的,学习了。