我正在使用SQL Server 2014.我的Web应用程序的一个功能是上传CSV文件,并将数据导入我的数据库(称为 TMPA
)中的表(称为 TF
) .
我不知道该怎么做 .
string excelPath = Server.MapPath("~/Files/") + Path.GetFileName(FileUpload2.PostedFile.FileName);
FileUpload1.SaveAs(excelPath);
SqlConnection con = new SqlConnection(@"Data Source=SAMSUNG-PC\SQLEXPRESS;Initial Catalog=TMPA;Persist Security Info=True");
StreamReader sr = new StreamReader(excelPath);
string line = sr.ReadLine();
string[] value = line.Split(',');
DataTable dt = new DataTable();
DataRow row;
foreach (string dc in value)
{
dt.Columns.Add(new DataColumn(dc));
}
while (!sr.EndOfStream)
{
value = sr.ReadLine().Split(',');
if (value.Length == dt.Columns.Count)
{
row = dt.NewRow();
row.ItemArray = value;
dt.Rows.Add(row);
}
}
SqlBulkCopy bc = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock);
bc.DestinationTableName = "TF";
bc.BatchSize = dt.Rows.Count;
con.Open();
bc.WriteToServer(dt);
bc.Close();
con.Close();
我尝试了这段代码,但它不起作用 .
PS: TF
列的列数多于CSV文件的列数:某些列是计算出来的,应在每次插入后自动计算 .
这是我的CSV文件的画布:4列:
IdProduit,Mois,Reel,Budget
IdProduit
是一个字符串, Mois
是一个日期, Reel
和 Budget
是浮点数 .
另一方面,我的SQL Server表如下所示:
|IdProduit|Mois|Reel|Budget|ReelPreviousMois|VarReelBudget|VarReelPrvM|...
|---------|----|----|------|----------------|-------------|-----------|-----
所有其他列应为null或自动计算 .
帮我 !
3 回答
我知道这是一个老问题,但对于任何可能感兴趣的人 .
除非您确定您的文件永远不会很大,否则您应该避免将整个批处理加载到内存中并将其全部发送到SQL Server,就像使用DataTable方法和(我认为)您接受的答案一样 . 您可能在客户端(在这种情况下是您的文件处理服务器)或更糟糕的是在SQL Server端冒着内存不足的风险 . 您可以通过使用SqlBulkCopy类和IDataReader接口的实现来避免这种情况 .
我写了一个我认为可能对你这样的案件感兴趣的软件包 . 代码看起来像这样:
对于更复杂的方案,还有其他配置选项(灵活列映射,csv文件中不存在的其他静态列值,值转换) . package是开源的(project on Github),应该适用于.NET Core和.NET Framework .
作为旁注,SQL Server恢复模式在进行大量SQL导入时可能很重要 . 尽可能使用Simple或Bulk Logged来避免巨大的事务文件 .
你正走在正确的道路上 . 在将数据插入SQL Server时,使用SqlBulkCopy将提供最佳性能 . 但是,与编写自己的Csv解析器相反,我将通过Microsoft.VisualBasic程序集中的TextFieldParser类使用.NET Framework中提供的恒星解析器 . 您可能需要进行一些挖掘以查看SqlBulkCopy是否允许使用部分数据集 . 我不相信它,但您可以将缺少的列添加到DataTable中,然后再将其作为变通方法发送到SqlBulkCopy .
我使用这个名为Filehelpers的开源.net库修复了它 . 这是链接:http://www.filehelpers.net/
这是我做的:
这是背后的代码: