如何从excel文件中优化插入到3600行的sql表中

时间:2014-03-19 14:11:40

标签: c# sql-server excel

我有一个最初有大约600行的Excel文件,我能够将excel文件转换为数据表,所有内容都正确地插入到sql表中。

Excel文件现在有3,600行,并且有一些类型的问题没有引发错误,但是在5分钟左右之后,所有行仍未插入到sql表中。

现在,当将Excel文件转换为内存数据表时,这种情况发生得非常快,但是当循环数据表并插入到sql表中时,我丢失数据并且速度非常慢,但是我是这样做的。我没有收到任何错误。

首先,在每个插页上,我必须与数据库建立新连接并插入记录,我已经知道这非常非常错误,我希望得到一些指导这个sql专业人员之一。

处理具有3,600条记录/行的内存数据表的正确方法是什么,而没有创建3,600个新连接?

- 以下是处理excel文件的代码,这很快就会发生.--

public static async Task<DataTable> ProcessExcelToDataTableAsync(string pathAndNewFileName, string hasHeader/*Yes or No*/)
            {

                return await Task.Run(() =>
               {
                   string conStr = "", SheetName = "";

                   switch (Path.GetExtension(pathAndNewFileName))
                   {
                       case ".xls": //Excel 97-03
                           conStr = ConfigurationManager.ConnectionStrings["Excel03ConString"].ConnectionString;
                           break;
                       case ".xlsx":
                           conStr = ConfigurationManager.ConnectionStrings["Excel07ConString"].ConnectionString;
                           break;
                   }
                   conStr = String.Format(conStr, pathAndNewFileName, hasHeader);
                   OleDbConnection connExcel = new OleDbConnection(conStr);
                   OleDbCommand cmdExcel = new OleDbCommand();
                   OleDbDataAdapter oda = new OleDbDataAdapter();
                   DataTable dt = new DataTable();
                   cmdExcel.Connection = connExcel;

                   //Get the name of First Sheet
                   connExcel.Open();
                   DataTable dtExcelSchema;
                   dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                   SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
                   connExcel.Close();

                   //Read Data from First Sheet
                   connExcel.Open();
                   cmdExcel.CommandText = "SELECT * From [" + SheetName + "]";
                   oda.SelectCommand = cmdExcel;
                   oda.Fill(dt);

                   connExcel.Close();
                   cmdExcel.Dispose();
                   oda.Dispose();

                   if (File.Exists(pathAndNewFileName))
                   {
                       File.Delete(pathAndNewFileName);
                   }

                   return dt;
               });
    }

- 这是处理内存数据表并将每个新记录插入sql表的代码,这是事情停止工作,没有可见错误,但只是不返回或工作 -

* *我需要一种更好的方法来优化此功能,其中记录被插入到sql表中。

     static async Task<ProcessDataTablePartsResult> ProcessDataTablePartsAsync(int genericCatalogID, DataTable initialExcelData)
            {
                //@GenericCatalogID   INT,
                //@Number             VARCHAR(50),
                //@Name               VARCHAR(200),
                //@Length             DECIMAL(8,4),
                //@Width              DECIMAL(8,4),
                //@Height             DECIMAL(8,4),
                //@ProfileID          TINYINT,
                //@PackageQty         DECIMAL(9,4),
                //@CategoryID         INT,
                //@UnitMeasure        VARCHAR(10),
                //@Cost               MONEY,
                //@PartID             INT OUT
                return await Task.Run(() =>
                {
                    DataTable badDataTable = null,
                              goodDataTable = initialExcelData.Clone();

                    goodDataTable.Clear();

                    int newPartID = 0,
                        currIx = 0,
                        numGoodRows = initialExcelData.Rows.Count,
                        numBadRows = 0;

                    List<int> badIndexes = new List<int>();
                    List<int> goodIndexes = new List<int>();
                    List<Profile> profiles = GenericCatalogManagerBL.GetProfiles(_genericCNN);
                    List<Category> categories = GenericCatalogManagerBL.GetAllCategoryNameID(_genericCNN);

                    Func<string, byte> getProfileID = delegate(string x)
                    {
                        return profiles.Where(p => p.TheProfile.ToLower().Replace(" ", "") == x.ToLower().Replace(" ", "")).FirstOrDefault().ID;
                    };

                    Func<string, int> getCategoryID = delegate(string x)
                    {
                        return categories.Where(c => c.Name.ToLower().Replace(" ", "") == x.ToLower().Replace(" ", "")).FirstOrDefault().ID;
                    };

                    foreach (DataRow r in initialExcelData.Rows)
                    {
                        try
                        {
                            IPart p = new Part
                            {
                                GenericCatalogID = genericCatalogID,
                                Number = r["Number"].ToString(),
                                Name = r["Name"].ToString(),
                                Length = decimal.Parse(r["Length"].ToString()),
                                Width = decimal.Parse(r["Width"].ToString()),
                                Height = decimal.Parse(r["Height"].ToString()),
                                ProfileID = getProfileID(r["Profile"].ToString()),
                                CategoryID = getCategoryID(r["Category"].ToString()),
                                PackageQty = int.Parse(r["PackageQty"].ToString()),
                                UnitMeasure = r["UnitMeasure"].ToString(),
                                Cost = decimal.Parse(r["Cost"].ToString())
                            };

                            GenericCatalogManagerBL.InsertPart(_genericCNN, p, out newPartID);
                            goodIndexes.Add(currIx);
                        }
                        catch (Exception)
                        {
                            numBadRows++;
                            numGoodRows--;
                            badIndexes.Add(currIx);
                        }
                        currIx++;
                    }

                    for (int i = 0; i < goodIndexes.Count; i++)
                    {
                        goodDataTable.ImportRow(initialExcelData.Rows[goodIndexes[i]]);
                        initialExcelData.Rows[goodIndexes[i]].Delete();

                    }
                    initialExcelData.AcceptChanges();
                    goodDataTable.AcceptChanges();

                    if (initialExcelData.Rows.Count > 0)
                    {
                        badDataTable = initialExcelData;
                    }

                    return new ProcessDataTablePartsResult(numGoodRows, numBadRows, badDataTable, goodDataTable);
                });
            }

**--Here is the entire flow of the function--**

 public static async Task<GenericPartsReport> ProcessGenericPartsAsync(int genericCatalogID, MembershipUser user, HttpRequest request, bool emailReport, bool hasHeaders)
        {
            byte[] fbytes = new byte[request.ContentLength];
            request.InputStream.Read(fbytes, 0, fbytes.Length);

            string pathAndNewFileName = Path.GetRandomFileName() + Path.GetExtension(request.Headers["X-FILE-NAME"]),
                   badReportTableString = "",
                   goodReportTableString = "";

            GenericPartsReport report = new GenericPartsReport();

            //get the users temp folder
            pathAndNewFileName = UtilCommon.SiteHelper.GetUserTempFolder(user, request) + pathAndNewFileName;

            File.WriteAllBytes(pathAndNewFileName, fbytes);

            //process the excel file first
            DataTable excelDataTable = await ProcessExcelToDataTableAsync(pathAndNewFileName, hasHeaders ? "Yes" : "No");

            ProcessDataTablePartsResult processedResult = await ProcessDataTablePartsAsync(genericCatalogID, excelDataTable);

            if (processedResult.BadDataTable != null)
            {
                if (processedResult.BadDataTable.Rows.Count > 0)
                {
                    badReportTableString = await BuildTableReportAsync(processedResult.BadDataTable, "AlumCloud Parts Not Added Report");
                    processedResult.BadDataTable.Dispose();
                }
            }

            if (processedResult.GoodDataTable != null)
            {
                if (processedResult.GoodDataTable.Rows.Count > 0)
                {
                    goodReportTableString = await BuildTableReportAsync(processedResult.GoodDataTable, "AlumCloud Parts Added Report");
                    processedResult.GoodDataTable.Dispose();
                }
            }

            report.Report = "A total number of (" + processedResult.NumberOfGoodRows + ") records was added to your generic catalog.<br/><br/>A total number of (" + processedResult.NumberOfBadRows + ") records were excluded from being added to your generic catalog.";

            if (processedResult.NumberOfBadRows > 0)
            {
                report.Report += "<br/><br/>You can review an excel file that meets the standards here: <a href='" + _exampleExcelFile + "'>How to format a part excel file</a>.";
                report.HasBadRows = true;
            }

            if (processedResult.NumberOfGoodRows > 0)
            {
                report.Report += "<br/><br/><b>Below is all of the parts that were added to your generic catalog<b/><br/><br/>" + goodReportTableString;
            }

            if (processedResult.NumberOfBadRows > 0)
            {
                report.Report += "<br/><br/><b>Below is all of the parts that were not added to your generic catalog</b><br/><br/>" + badReportTableString;
            }

            if (emailReport)
            {
                AFCCIncCommonUtil.EmailUtil.SendMailToThreadPool(user.Email, _supportEmail, report.Report, "AlumCloud Generic Catalog Parts Report", true);
            }

            excelDataTable.Dispose();
            return report;
        }

- 这是一个永不返回或处于某种状态的功能 -

  ProcessDataTablePartsResult processedResult = await ProcessDataTablePartsAsync(genericCatalogID, excelDataTable);

0 个答案:

没有答案