通过OleDBDataReader从大型Excel文件进​​行C#批量复制,抛出内存不足异常

时间:2019-02-24 19:30:37

标签: c# excel sqlbulkcopy

我有一个很大的Excel文件(530K行且列很多)。最终为.xlsb格式的247MB。我正在尝试使用C#中的BulkCopy导入SQL Server,但是我遇到的问题是,一旦运行ExecuteReader()命令,数据读取器甚至在开始读取文件之前,都会耗尽内存。

string exlConnString = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={_filepath};Extended Properties=\"Excel 12.0;HDR=YES;\"";
string sqlQuery = $"SELECT * FROM [{SheetName}]";
using OleDbConnection conn = new OleDbConnection(_connstring)) {    
   OleDbCommand exlCmd = new OleDbCommand(sqlQuery, conn)
   conn.Open();
   OleDbDataReader dr = exlcmd.ExecuteReader(); <---NEVER GETS PAST THIS LINE BEFORE RUNNING OUT OF MEMORY.
   SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnString);
   bulkCopy.DestinationTable = TableName;
   while(dr.Read()) {
      bulkcopy.WriteToServer(dr);
   }
   dr.Close();
}

我正在x86模式下运行,因为我得到一个错误,即本地计算机上未安装ACE数据库,并且公司策略限制使我无法下载并安装在x64模式下运行它所需的文件。

当我在较小的文件上对其进行测试时,该代码可以正常工作,但在此较大的文件上对其进行测试时,该代码就可以正常工作,因此,绝对是文件大小引起了该问题。任何建议或帮助,将不胜感激。当大容量副本用于处理大数据集时,内存副本用完并没有多大意义,这也意味着文件大小也将变得很大...

是的,我知道我应该能够在SQL Server中使用OPENROWSET或OPENDATASOURCE导入此文件,但是该文件也已关闭并且不会启用它,因此这不是一个选择。

2 个答案:

答案 0 :(得分:0)

接下来是你的问题。

当您尝试ExecuteReader DataReader尝试将所有数据从excel文件读取到内存时。您可以考虑一下,就像通过OleDbProvider与excel合作的专业。

所以我的建议是使用csv文件而不是excel,因为使用csv文件,您可以逐行读取和解析它们。为此,我建议您使用CSV helper

答案 1 :(得分:0)

请参阅此代码。 此处的dtExcelData是数据表变量,而da是OleDbDataAdapter变量。

 string excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={_filepath};Extended Properties='Excel 12.0;HDR=YES';";

                // Create Connection to Excel Workbook
                using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
                {
                    connection.Open();
                    da = new OleDbDataAdapter("Select * FROM [Sheet1$]", connection);    
                    da.Fill(dtExcelData);

                    //store data in sql server database table
                   // below connection string "conString" is I mention in app.config file.(sql server connection string to store data in sql server database)
                    string str = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
                    using (SqlConnection con = new SqlConnection(str))
                    {
                        // Bulk Copy to SQL Server
                        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(con))
                        { 
                            bulkCopy.DestinationTableName = "TableName";
                            con.Open();
                            bulkCopy.WriteToServer(dtExcelData);
                            con.Close();
                        }
                    }                        
                    connection.Close();
                }

如果对您有用,请将其标记为答案。 :)