繁体   English   中英

使用C#和asp.net将CSV文件导入SQL

[英]Import a CSV file to SQL with C# and asp.net

我正在使用SQL Server2014。我的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|...
  |---------|----|----|------|----------------|-------------|-----------|-----

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

帮我 !

我使用名为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 ); 

} 

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

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

除非您确定文件永远不会很大,否则应避免像DataTable方法和(我认为)您接受的答案一样,将整个批处理加载到内存中并立即将其全部发送到SQL Server。 您可能会冒着在客户端(在这种情况下,您的文件处理服务器)的内存不足异常的风险,或者更糟的是,在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文件中不存在的其他静态列值,值转换),还有其他配置选项。 软件包是开源的( 在Github上项目 ),并且可以在.NET Core和.NET Framework上运行。

另外,在进行大量SQL导入时,SQL Server恢复模式可能很重要。 只要有可能,请使用“简单”或“大容量日志记录”以避免大量的事务文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM