2016-08-24 144 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