【问题标题】:Inserting data from CSV in mutiple tables via ASP.NET (C#), SQL Server通过 ASP.NET (C#)、SQL Server 在多个表中插入来自 CSV 的数据
【发布时间】:2015-06-04 10:06:24
【问题描述】:

我有一个包含 7 列的 CSV 文件,用户必须上传该文件才能将其添加到数据库中。 我在阅读 CSV 并将所有信息放在一个表中找到了一些帮助,但是,数据必须分布在三个表中。

我将所有数据插入到 1 个表中的代码:

        protected void Upload(object sender, EventArgs e)
    {
        //Upload and save the file
        string csvPath = Server.MapPath("~/Temp/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
        FileUpload1.SaveAs(csvPath);

        DataTable dt = new DataTable();
        dt.Columns.AddRange(new DataColumn[7] { 
        new DataColumn("Title", typeof(string)),
        new DataColumn("Artist", typeof(string)),
        new DataColumn("Years", typeof(string)),
        new DataColumn("Position", typeof(string)),
        new DataColumn("Senddate", typeof(string)),
        new DataColumn("Sendfrom", typeof(string)),
        new DataColumn("Sendtill", typeof(string))});


        string csvData = File.ReadAllText(csvPath);
        foreach (string row in csvData.Split('\n'))
        {
            if (!string.IsNullOrEmpty(row))
            {
                dt.Rows.Add();
                int i = 0;
                foreach (string cell in row.Split(';'))
                {
                    dt.Rows[dt.Rows.Count - 1][i] = cell;
                    i++;
                }
            }
        }

        string consString = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
        using (SqlConnection con = new SqlConnection(consString))
        {
            using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con))
            {
                //Set the database table name
                sqlBulkCopy.DestinationTableName = "dbo.ingevoerd";
                con.Open();
                sqlBulkCopy.WriteToServer(dt);
                con.Close();
            }
        }
    }

如您所见,它需要 7 列,并将它们放在表中 [dbo].[ingevoerd]

如何拆分数据以将“标题”和“年份”列放入名为 Song 的表中,将“艺术家”列放入名为 Artiest 的表中,以及“位置”、“发送日期”、“发送自”和“发送至” ' 在名为 Lijst 的表中?

如需了解更多信息,请发表评论。

【问题讨论】:

  • 恕我直言,您应该改用 SSIS 来完成此任务。

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


【解决方案1】:

恕我直言,这不是处理此上传的最佳方式,因为内容不是您可以轻松批量上传的平面数据;应该链接许多实体(至少 3 个)。

我会采用“旧式”方法,即使用适当的参数为每一行调用插入。

您在读取 ​​CSV 时已经在循环整个记录集,所以我会做类似的事情:

    protected void Upload(object sender, EventArgs e)
    {
        //Upload and save the file
        string csvPath = Server.MapPath("~/Temp/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
        FileUpload1.SaveAs(csvPath);

        string consString = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
        using (SqlConnection con = new SqlConnection(consString))
        {
            con.Open();
            using (SqlTransaction tran = con.BeginTransaction())
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.Connection = con;
                cmd.Transaction = tran;
                cmd.CommandType = System.Data.CommandType.StoredProcedure;
                cmd.CommandText = "your_sp_name_here";
                cmd.Parameters.Add(new SqlParameter("@title",System.Data.SqlDbType.NVarChar));
                cmd.Parameters.Add(new SqlParameter("@artist", System.Data.SqlDbType.NVarChar));
                // other parameters follow
                // ...

                string csvData = File.ReadAllText(csvPath);
                foreach (string row in csvData.Split('\n'))
                {
                    if (!string.IsNullOrEmpty(row))
                    {
                        // for every row call the command and fill in the parameters with proper values
                        cmd.Parameters["@title"].Value = row[0];
                        cmd.Parameters["@artist"].Value = row[1];
                        // ...
                        cmd.ExecuteNonQuery();
                    }
                }

                // when done commit the transaction
                tran.Commit();
            }
        }
    }

在您的存储过程中处理相关表中数据的“拆分”,采取所有必要的步骤来避免重复,并可能在表之间链接数据:

create procedure your_sp_name_here(@title nvarchar(50), @artist nvarchar(50), @year int)
as
begin
 -- add logic & checks here if needed
 -- ...
 -- ...

 -- if everything is ok insert the rows
 insert into songs (title, year) values (@title, @year)
 insert into Artiest (Artist) values (@artist)
end

【讨论】:

  • 感谢您的回答,我会看看这个并尝试实现它!
  • 当您有大量数据时,我还建议您使用 StreamReader 来读取所有内容
  • 另一种选择是使用custom library,这大大简化了与 CSV 文件的交互
【解决方案2】:

您是否研究过列映射?

查看 stackoverflow.com/questions/17469349/mapping-columns-in-a-datatable-to-a-sql-table-with-sqlbulkcopy

【讨论】:

  • 不,我不知道列映射,不过会看看。
猜你喜欢
  • 2010-11-22
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多