咨询区
-
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 null
for (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());
}
}
点评区
在现实开发中,这种需求还是蛮常见的,学习了。