2017-04-03 22 views
2

我有一个SQL表,有两列:OldValue和NewValue。我在Excel电子表格中有两个相同的列。我想找到最快捷的方式来遍历数据库和Excel电子表格,检查数据库中的OldValue列是否与电子表格中的OldValue列相同。通过SQL数据库列对Excel列循环最快的方式 - C#

我的逻辑工作,使我遍历整个sql列(333228记录)寻找与Excel列有153 000行匹配。这个迭代是性能沉重,需要几个小时甚至没有完成 - 最终挂起。我怎样才能快速做到这一点? 153 000 x 333228 = 24亿次计算密集型迭代。

我在这里读到https://codereview.stackexchange.com/questions/47368/looping-through-an-excel-document-in-c但没有得到我正在寻找的东西。该代码的作品,并已发现500场比赛,但考虑到我需要通过数据库中的333228记录缓慢。

List<sim_info> exel_sims = new List<sim_info>(); 

      Microsoft.Office.Interop.Excel.Application Excel_app = new Microsoft.Office.Interop.Excel.Application(); 
      Microsoft.Office.Interop.Excel.Workbooks work_books = Excel_app.Workbooks; 


      string excel_file_path = Application.StartupPath + "\\TestSample"; 
      Microsoft.Office.Interop.Excel.Workbook work_book = work_books.Open(excel_file_path); 
      work_book.SaveAs(excel_file_path + ".csv", Microsoft.Office.Interop.Excel.XlFileFormat.xlCSVWindows); 
      Microsoft.Office.Interop.Excel.Sheets work_sheets = work_book.Worksheets; 
      Microsoft.Office.Interop.Excel.Worksheet work_sheet = (Microsoft.Office.Interop.Excel.Worksheet)work_sheets.get_Item(1); 



       for (int j = 2; j < work_sheet.Rows.Count; j++) 
       { 
        try 
        { 
         temp_sim_info.msisdn = cell_to_str(work_sheet.Cells[j, 1]).Trim(); 
         temp_sim_info.mtn_new_number = cell_to_str(work_sheet.Cells[j, 8]).Trim(); 
         temp_sim_info.status = cell_to_str(work_sheet.Cells[j, 9]).Trim(); 

         if (temp_sim_info.msisdn.Length < 5 || temp_sim_info.mtn_new_number.Length > 15) //Valid cellphone number length contains 11 digits +27XXXXXXXXX/14 digits for the new msisdn. This condition checks for invalid cellphone numbers 
         { 
          if (zero_count++ > 10) 
           break; 
         } 
         else 
         { 
          zero_count = 0; 

          exel_sims.Add(temp_sim_info); 
          if (exel_sims.Count % 10 == 0) 
          { 
           txtExcelLoading.Text = exel_sims.Count.ToString(); 
          } 
         } 
        } 
        catch 
        { 
         if (zero_count++ > 10) 
          break; 
        } 

        // } 


        txtExcelLoading.Text = exel_sims.Count.ToString(); 
        work_sheet.Columns.AutoFit(); 

        for (int i = 0; i < TestTableInstance.Rows.Count; i++) 
        { 
         string db_oldNumbers = ""; 
         string db_CellNumber = ""; 

         if (!TestTableInstance.Rows[i].IsNull("OldNumber")) 
          db_oldNumbers = TestTableInstance[i].OldNumber; 
         else 
          db_oldNumbers = TestTableInstance[i].CellNumber; 
         if (!TestTableInstance.Rows[i].IsNull("CellNumber")) 
          db_CellNumber = temp_sim_info.mtn_new_number; 

         for (int k = 0; k < exel_sims.Count; k++) 
         { 

           sim_info sim_Result = exel_sims.Find(x => TestTableInstance[i].CellNumber == x.msisdn); 

            if (TestTableInstance[i].CellNumber == exel_sims[k].msisdn && sim_Result != null) 
            { 
             //If match found then do logic here 
            } 
         } 
        } 
     } 
     MessageBox.show("DONE"); 

TableInstance是在内存中加载的数据库的DataSet。第二个内部循环迭代每个记录的整个DB列,直到它在电子表格的OldValue列的第一行中找到匹配项。

我的代码作品当我有一个由800行组成的Excel表格和一个由1000条记录组成的数据库表格时,我们对它进行了尝试和测试。它在5分钟内完成。但是,对于数十万条记录,它会挂起数小时

+2

你为什么不加载了Excel中的SQL和针对它运行一个简单的查询? – Jens

+0

你标记了这个mysql和sql-server。这是什么?而且这里需要一个数据库选项卡,因为无论如何你都得到了数据集中的结果集? – GuidoG

+0

@Jens使用批量复制在Sql中加载excel? –

回答

0

正是!为什么你使用C#来做到这一点?将Excel文件加载到数据库中的临时表中,并在您的实际SQL表(据称拥有Excel文件中的所有数据)和临时表(或视图)之间进行比较。这种比较应该在几秒钟内完成。

select * 
from dbtest02.dbo.article d2 
left join dbtest01.dbo.article d1 on d2.id=d1.id 

左边的加入显示左表 “dbtest02.dbo.article” 的所有行,即使有在 “dbtest01.dbo.article” 不匹配:

OR

select * from dbtest02.dbo.article 
except 
select * from dbtest01.dbo.article 

请参阅下面的链接,了解如何执行此操作的其他一些想法。

https://www.mssqltips.com/sqlservertip/2779/ways-to-compare-and-find-differences-for-sql-server-tables-and-data/

+0

谢谢。有效!我使用导入向导将数据复制到SQL中的一个虚拟表,然后运行您的左连接,几秒钟后,我很高兴。 –

+0

要标记为帮助你的答案?只需给它加票,然后单击复选标记。 – ryguy72