2016-08-24 96 views
0

我寫了一個Excel-VBA代碼來訪問一個SQL Server數據庫(它在網絡中,而不是我的電腦),它有一個表10專欄和約3000條記錄(基本上是按揭貸款)。Excel-VBA訪問sql服務器表選擇和插入太慢

代碼循環遍歷這些記錄,併爲每個記錄執行一些基本計算以生成大約180條記錄(每個抵押貸款的攤餘表),然後將它們插入到新表中(總計約540000條記錄)。

它是這樣的(我用的可讀性意見,避免在此大碼):

Sub amortizationScheduleToSQLServer() 

     'Some calculation variables go here 

     Dim cn As ADODB.Connection 
     Dim rs As ADODB.Recordset 
     Dim rs2 As ADODB.Recordset 

     Set cn = New ADODB.Connection 
     Set rs = New ADODB.Recordset 
     Set rs2 = New ADODB.Recordset 

     Server_Name = "..." 
     Database_Name = "..." 
     cn.Open "PROVIDER=SQLOLEDB;DATA SOURCE=" & Server_Name & ";INITIAL CATALOG=" & Database_Name & ";Integrated Security=SSPI;" 
     SQLStr = "SELECT * FROM TABLE_PRETS" 
     Set rs = cn.Execute(SQLStr) 

     If Not (rs.EOF And rs.BOF) Then 
      rs.MoveFirst 
      Do Until rs.EOF = True 

       'Assigning data from table to variables here 

       'Basic multiplications here, nothing heavy 

       For i = 1 To paymentsNumber 

        'More basic calculations and assigning here 

        SQLStr = "INSERT INTO TABLE_AMORTISSEMENT (N_CONTRAT,MOIS,DATE_ECHEANCE,MENSUALITE,SOLDE_DEPART,CAPITAL_AMORTI," _ 
         & "INTERET_HT,TVA,ASSURANCE,CAPITAL_RESTANT)" _ 
         & "VALUES (" & loanID & ", " & i & ", '" & DateAdd("m", i, startDate) & "', " & Replace(monthlyPayment, ",", ".") & ", " _ 
         & Replace(startingBalance, ",", ".") & ", " & Replace(principal, ",", ".") & ", " & Replace(interestPaymentBT, ",", ".") _ 
         & ", " & Replace(taxOnInterest, ",", ".") & ", " & Replace(insurancePayment, ",", ".") & ", " _ 
         & Replace(remainingBalance, ",", ".") & ");" 
        Set rs2 = cn.Execute(SQLStr) 
       Next i 

       rs.MoveNext 
      Loop 
     Else 
      MsgBox "There are no records in the recordset." 
     End If 

     MsgBox "Finished looping through records. " 

     If rs.State = 1 Then 
      rs.Close 
      Set rs = Nothing 
     End If 

     If rs2.State = 1 Then 
      rs2.Close 
      Set rs2 = Nothing 
     End If 

     If cn.State = 1 Then 
      cn.Close 
      Set cn = Nothing 
     End If 

    End Sub 

我計時這段代碼通過刪除這一行省略INSERT後:

集RS2 = cn.Execute(SQLStr)

該代碼基本上循環通過3000條記錄,並使未使用的字符串,它運行約9 seco nds。 (我不知道這對於Excel-VBA/SQL Server是否可以接受)。

但是放回INSERT執行行使代碼運行1小時以製作540000記錄表。這是正常的嗎?我如何優化這段代碼?

+1

如果程序運行1小時,則表示每秒產生150條新記錄。考慮到這些是昂貴的操作,程序花費很長時間才能完成並不奇怪。我懷疑你可以對此做很多事情,除了在第一個'SQLStr'語句中查詢更少的記錄,而不是所有的記錄。也就是說,如果這是可取的話。 – Miqi180

+0

謝謝你的回答。實際上,我將在稍後將此代碼移至VB.NET,並且我想知道它是否會運行得更快。 – Naucle

+1

您可以嘗試在一個巨大的語句中添加記錄,但不確定它是否會更快。 IE: 'INSERT INTO MyTable的(名稱,ID) VALUES( '第一',1), ( '第二',2), ( '第三',3), ( '四',4)' –

回答

1

這裏講的有點超出我的舒適範圍,但我看到的是cn.execute語句創建了一個永遠不會使用的記錄集(rs2)。根據ADO執行方法上的MSDN參考,可以使用選項(adExecuteNoRecords)在插入時停止創建記錄集。也許這會加快一點?

+0

這樣做後代碼運行速度提高了30%。謝謝你的回答。 – Naucle