首页 文章

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

提问于
浏览
0

我正在使用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|...
  |---------|----|----|------|----------------|-------------|-----------|-----

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

帮我 !

3 回答

  • 1

    我知道这是一个老问题,但对于任何可能感兴趣的人 .

    除非您确定您的文件永远不会很大,否则您应该避免将整个批处理加载到内存中并将其全部发送到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 Server恢复模式在进行大量SQL导入时可能很重要 . 尽可能使用Simple或Bulk Logged来避免巨大的事务文件 .

  • 0

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

  • 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 ); 
    
    }
    

相关问题