2012-09-12 39 views
0

我有一些代碼,我希望有人可以關注性能改進。我有一個需要每週導入的電子表格。該表有112列和約35,000行。我的代碼有效,但大約需要20分鐘才能導入數據。 excel列名與數據庫列名不匹配(我繼承了這個)。這是我正在使用的代碼。 (我刪除了很多的領域,所以它更容易閱讀)將excel表格導入到sql數據庫VB網絡客戶端

'Connection String to Excel Workbook 
    Dim excelConnectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & MyFile & ";Extended Properties=""Excel 12.0;HDR=Yes;""" 

    ' Create Connection to Excel Workbook 
    Using connection As New System.Data.OleDb.OleDbConnection(excelConnectionString) 

     'List columns you need from the Excel file 
     Dim command As New System.Data.OleDb.OleDbCommand("Select * FROM [" & txtSheetName.Text & "$]", connection) 
     connection.Open() 

     ' Create DbDataReader to Data Worksheet 
     Using dr As System.Data.OleDb.OleDbDataReader = command.ExecuteReader() 

      Dim strSql As String = "" 

      strSql = "INSERT INTO MyTestTable (" & _ 
         "State, [Store Code], [Store Name], [Store Zone Code], [Store Zone Code Name], " & _ 
         "WeekProd, YTDNew, " & _ 
         "UpdatedBy, DateUpdated" & _ 
        ") VALUES (" & _ 
         "@State, @StoreCode, @StoreName, @StoreZoneCode, @StoreZoneCodeName, " & _ 
         "@WeekProd, @YTDNew, " & _ 
         "@UpdatedBy, @DateUpdated" & _ 

      Try 
       If dr.HasRows() Then 

        While dr.Read() 

         If Convert.ToString(dr.Item(0)) <> "" Then 

          Dim MyZone As String = Convert.ToString(dr.Item(1)) 
          MyZone = StrConv(MyZone, vbProperCase) 

          Dim cmd As New SqlClient.SqlCommand 
          cmd.Connection = cn 
          cmd.CommandType = CommandType.Text 
          cmd.CommandText = strSql 

          cmd.Parameters.Add("@State", SqlDbType.VarChar).Value = "" 
          cmd.Parameters.Add("@StoreCode", SqlDbType.VarChar).Value = Convert.ToString(dr.Item(0)) 
          cmd.Parameters.Add("@StoreName", SqlDbType.VarChar).Value = MyZone 
          cmd.Parameters.Add("@StoreZoneCode", SqlDbType.VarChar).Value = Convert.ToString(dr.Item(2)) 
          cmd.Parameters.Add("@StoreZoneCodeName", SqlDbType.VarChar).Value = Convert.ToString(dr.Item(3)) 
          cmd.Parameters.Add("@WeekProd", SqlDbType.Float).Value = Convert.ToDecimal(dr.Item(93)) 
          cmd.Parameters.Add("@YTDNew", SqlDbType.Float).Value = Convert.ToDecimal(dr.Item(94)) 
          cmd.Parameters.Add("@UpdatedBy", SqlDbType.VarChar).Value = MyUser.Substring(MyUser.Length - 4) 
          cmd.Parameters.Add("@DateUpdated", SqlDbType.Date).Value = Date.Today() 

          cmd.ExecuteScalar() 

         End If 

        End While 

       End If 

      Catch ex As Exception 

       lblMessage.Text = ex.Message 
       Exit Sub 

      Finally 

       cn.Close() 
       cn = Nothing 

      End Try 

     End Using 

    End Using 

回答

0

不會承諾這將使世界着火表現明智,但它可能會有所幫助。

我的第一個想法是而不是爲Excel表中的每一行創建一個新的SqlCommand對象和參數集。我會創建它一個時間(根據您的數據大小,應該節省大約35K對象實例的開銷),在讀取器循環外部建立參數名稱,然後調用SetParameter將每列的值設置爲每個遍歷Excel中的行。這應該交易大約35K *(實際字段數量)的開銷參數另外要求對現有參數進行setparameter調用。而且我還會將調用類型更改爲ExecuteNonQuery而不是ExecuteScalar。

現在,通常情況下,傳統的看法認爲,只有在需要時纔打開/關閉與數據庫的連接,而且我認爲這在此結構中是隱含的(每個插入件的打開/關閉),但在這種情況下對於這樣的數據更新場景,我認爲這將是一個合理的例外。

+0

聽起來很不錯。我會試一試。 – Mike

+0

@Mike - 你的查詢有任何運氣與mods? –