【问题标题】:sql bulk copy will not upload data to database using file streamsql批量复制不会使用文件流将数据上传到数据库
【发布时间】:2012-03-14 09:08:54
【问题描述】:

我正在通过文件上传控件上传文件,然后流阅读器读取文件 itno 数据表,然后 sql 批量复制将数据表复制到我的 sql 数据库并填充相应的列。有人看到下面的代码有什么问题吗?我没有收到错误消息,但似乎它正在挂起 IIS 进程。我不能进去从文件夹中删除 csv 文件,因为它说该过程仍在工作。

    protected void btnUpload_Click(object sender, EventArgs e)
    {

        //upload file to the gencouploadfiles folder
        UploadFile();

        //fetch CSV file from the folder
        string strFilePath = Server.MapPath("GencoUploadFiles") + "\\" + "GencoUploadFile.txt";

        //perform sql bulk copy
        PerformBulkCopy(GencoUpload(strFilePath));

        //delete the file from the folder
    }



    public void UploadFile()
    {
        if (fileUpload1.HasFile)
        {
            FileInfo fileinfo = new FileInfo(fileUpload1.PostedFile.FileName);
            string strCsvFilePath = Server.MapPath("GencoUploadFiles") + "\\" + "GencoUploadFile.txt";
            fileUpload1.SaveAs(strCsvFilePath);
        }
    }


    public static DataTable GencoUpload(string filepath)
    {
        StreamReader sr = new StreamReader(filepath);
        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);
            }
        }
        return dt;
    }


    public void PerformBulkCopy(DataTable dt)
    {
        SqlConnection conStr = new SqlConnection(ConfigurationManager.ConnectionStrings["EDI"].ConnectionString);

        using (SqlBulkCopy bulkcopy = new SqlBulkCopy(conStr.ConnectionString))
        {
            bulkcopy.DestinationTableName = "dbo.GencoUploadTempTable";
            bulkcopy.BatchSize = dt.Rows.Count;
            conStr.Open();
            bulkcopy.WriteToServer(dt);
            bulkcopy.Close();
            conStr.Close();
        }
    }

【问题讨论】:

  • 你能用 SqlDataReader 代替 DataTable 吗?
  • SQL 批量复制应该可以正常工作,但我从未在网页中使用过它,仅在 Windows 服务中使用过。你能给我们一个文件大小的想法吗?看起来您基本上是一次性将整个文件批处理到服务器。执行此操作时,您是否检查过服务器的内存利用率?这基本上是将整个文件加载到数据表中时将其存储在内存中,因此如果文件很大,可能会降低服务器的性能。
  • 它应该可以正常工作;文件被上传到服务器,然后 SqlBulkCopy 从本地服务器文件系统完成到数据库 - 当然,前提是文件实际上已经上传(在这种情况下,文件被锁定在服务器端;-)
  • 我不认为批量复制是您的问题。看起来不错,但也许可以尝试去掉 batchsize。

标签: c# asp.net sqlbulkcopy


【解决方案1】:

简化您的代码;有很多方法可以将 csv 放入数据表 - 例如,请参阅 How to read a CSV file into a .NET Datatable。在上面的示例中,您似乎没有在完成阅读后关闭流...在返回之前添加 sr.Close() ,或者最好还是将声明包装在 using() 语句中:

  public static DataTable GencoUpload(string filepath) 
  { 
        DataTable dt = new DataTable(); 

        using(StreamReader sr = new StreamReader(filepath))
        { 
            string line = sr.ReadLine(); 
            string[] value = line.Split('|'); 

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

        return dt; 
    } 

这应该可以防止文件被锁定。

接下来要看的是检查数据表中是否真的有任何数据。放置一个断点并测试以查看您的加载代码是否实际工作;您正在向数据表添加行,但尚未定义列结构(即您只提供了名称而不是数据类型,因此您可能会遇到转换问题)。使用其他方法之一加载文件肯定会更容易:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 2013-09-27
    • 1970-01-01
    相关资源
    最近更新 更多