【问题标题】:Import a CSV file to SQL with C# and asp.net使用 C# 和 asp.net 将 CSV 文件导入 SQL
【发布时间】:2014-09-26 22:18:00
【问题描述】:

我正在使用 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 是日期,ReelBudget 是浮点数。

另一方面,我的 SQL Server 表如下所示:

  |IdProduit|Mois|Reel|Budget|ReelPreviousMois|VarReelBudget|VarReelPrvM|...
  |---------|----|----|------|----------------|-------------|-----------|-----

所有其他列应为空或自动计算。

帮帮我!

【问题讨论】:

  • 不要自己动手。而是使用codeproject.com/Articles/9258/A-Fast-CSV-Reader
  • 是否必须通过asp.net进行? SSIS 不是更好的选择吗?
  • @ThanosMarkou 如果我没听错的话,这是一项功能,而不是一次性加载。
  • 我建议您查看 CSVHelper 以避免自己摆弄 CSV 文件......
  • @rcdmk(我是她)正是它是网络应用程序的一个功能。这实际上是实习。我的客户-不是计算机科学专家或任何人-希望能够通过单击站点上的文件上传按钮将 csv 文件上传到数据库中-这是我无法做到的-,还有另一个 aspx 页面他可以在哪里看到桌子上的数据-这是我做的-

标签: c# sql asp.net sql-server csv


【解决方案1】:

我使用这个名为 Filehelpers 的开源 .net 库修复了它。 这是链接:http://www.filehelpers.net/

这就是我所做的:

 <asp:FileUpload ID="FileUpload1" runat="server" />
        <asp:Button ID="Button1" OnClick = "UploadF" runat="server" Text="Importer" />

下面是代码:

    [DelimitedRecord("|")]
    public class TBFtable 
{ 
    public string IdProduit; 
    public DateTime Mois; 
    public float Reel; 
    public float Budget; 

} 

    protected void UploadF(object sender, EventArgs e)

    {

        string excelPath = Server.MapPath("~/Files/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
        FileUpload1.SaveAs(excelPath);

        SqlServerStorage storage = new SqlServerStorage(typeof(TBFtable),ConfigurationManager.ConnectionStrings["bd"].ConnectionString);


         storage.InsertSqlCallback = new InsertSqlHandler(GetInsertSqlCust);

        TBFtable[] res = CommonEngine.ReadFile(typeof(TBFtable), excelPath) as TBFtable[]; 
        storage.InsertRecords(res);
        ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "alertMessage", "alert('Données enregistrées avec succès !')", true);
    }

    protected string GetInsertSqlCust(object record) 
{ 
    TBFtable obj = (TBFtable) record; 

    return String.Format("INSERT INTO TF (IdProduit, Mois, Reel, Budget ) " +  " VALUES ( '{0}' , '{1}' , '{2}' , '{3}'  ); ", obj.IdProduit, obj.Mois,obj.Reel, obj.Budget ); 

} 

【讨论】:

    【解决方案2】:

    您走在正确的道路上。将数据插入 SQL Server 时,使用 SqlBulkCopy 将提供最佳性能。但是,与编写自己的 Csv 解析器相反,我将使用 .NET Framework 通过 Microsoft.VisualBasic 程序集中的 TextFieldParser 类提供的出色解析器。您可能需要进行一些挖掘以查看 SqlBulkCopy 是否允许使用部分数据集。我不相信它,但您可以将缺少的列添加到您的 DataTable 中,然后将其发送到 SqlBulkCopy 作为一种解决方法。

    【讨论】:

      【解决方案3】:

      我知道这是一个老问题,但对于可能感兴趣的人来说。

      除非您确定您的文件永远不会很大,否则您应该避免将整个批次加载到内存中并将其一次性发送到 SQL Server,就像 DataTable 方法和(我认为)您接受的答案一样.您可能会在客户端(在这种情况下是您的文件处理服务器)或更糟糕的 SQL Server 端冒内存不足异常的风险。您可以通过使用 SqlBulkCopy 类和 IDataReader 接口的实现来避免这种情况。

      我写了一个包,我认为它可能会在您的情况下感兴趣。代码如下所示:

      var dataReader = new CsvDataReader("pathToYourCsv",
                  new List<TypeCode>(4)
                  {
                      TypeCode.String, //IdProduit
                      TypeCode.DateTime, //Mois
                      TypeCode.Double, //Reel
                      TypeCode.Double //Budget
                  });
      
              this.bulkCopyUtility.BulkCopy("tableName", dataReader);
      

      还有其他配置选项可用于更复杂的场景(灵活的列映射、csv 文件中不存在的其他静态列值、值转换)。 package 是开源的 (project on Github),应该可以在 .NET Core 和 .NET Framework 上运行。

      顺便说一句,在进行大量 SQL 导入时,SQL Server 恢复模式可能很重要。尽可能使用简单或批量记录以避免庞大的事务文件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-04
        • 2017-02-15
        • 1970-01-01
        • 2020-09-01
        • 2018-10-19
        • 1970-01-01
        相关资源
        最近更新 更多