有什么办法可以提高这个VBA循环的速度来将数据插入SQL?

时间:2016-02-04 01:07:16

标签: sql-server excel vba excel-vba

我有一个VBA循环,可以在SQL表中插入大约120,000行。

我已经读过,使用大型数据集的循环非常耗时(我已经发现,这需要10多分钟才能完成)

如果有人可以向我提出建议,可能会批量插入这些数据作为范围或什么?

谢谢你们!

Sub export_to_sql()

Dim conn As New ADODB.Connection
Dim RowNo As Long
Dim C1, C2, C3, C4 As String
Dim wbk As Workbook
Dim strFile As Variant
Dim shtname As String
ChDir "xxx"
strFile = Application.GetOpenFilename
If strFile = False Then
Exit Sub
Else: End If



    ' *** Open workbook first ***
    Set wbk = Workbooks.Open(strFile)
    shtname = ActiveWorkbook.Worksheets(1).Name
    lastrow = wbk.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row + 1
    With Sheets(shtname)

    'Open a connection to SQL Server
    conn.Open "Provider=SQLOLEDB;Data Source=SERVER\SQL2008R2;Initial Catalog=xxxxx;User ID=xx; Password=xxxxxxxx; "

    ' Delete table data
    conn.Execute "DELETE FROM EcommerceTablename"

    'Skip the header row
    RowNo = 2

    'Loop until empty cell in Col 1
    Do Until .Cells(RowNo, 1) = ""
        C1 = .Cells(RowNo, 1)
        C2 = .Cells(RowNo, 2)
        C3 = .Cells(RowNo, 3)
        C4 = .Cells(RowNo, 4)

        'Generate and execute sql statement to import the excel rows to SQL Server table

        conn.Execute "insert into EcommerceTablename ([Col_1_C], [Col_2_C], [Col_3_C], [Col_4_C]) values ('" & C1 & "', '" & C2 & "', '" & C3 & "', '" & C4 & "')"

        RowNo = RowNo + 1
    Loop


    conn.Close
    Set conn = Nothing

End With

End Sub

4 个答案:

答案 0 :(得分:2)

如果您真的想要速度,则应考虑使用批量复制实用程序bcp。让您的VBA为文件生成输出,然后让bcp将文件粘贴到数据库中。

我的语法在BCP上可能有些偏差,但我想通过一些调整你可以按照你想要的方式得到它:

  Dim outputArray(4) As String
  Dim col As Integer

  Set wbk = Workbooks.Open(strFile)

  Open "c:\Temp\UploadData.dat" For Output As #1

  With wbk.Sheets(1)
    lastrow = .Cells(Rows.Count, "A").End(xlUp).Row + 1
    RowNo = 2

    Do Until .Cells(RowNo, 1) = ""
      For col = 1 To 4
        outputArray(col) = .Cells(RowNo, col)
      Next col

      Print #1, Join(outputArray, "|")

      RowNo = RowNo + 1
    Loop

    conn.Open "<your connection string>"
    conn.Execute "DELETE FROM EcommerceTablename"
    conn.Close
    Set conn = Nothing

  End With

  Close #1

  System ("bcp EcommerceTablename in c:\Temp\UploadData.dat -S SERVER\SQL2008R2 " & _
      "-c -t""|"" -U xx -P xxxxxxxxxx")

同样,您可能希望查看这些内容以进行验证,但基本语法为:

bcp <table> <in/out (upload/download> <file> <options>

据我所知,我列出的选项是:

  • -S server
  • -U Userid
  • -P密码
  • -c字符输入(-n [ative]对于进行备份很有用)
  • -t delimiter

此外,如果您对表有权限,truncate明显快于delete from,如果你真正想做的就是擦除并重新加载表格。如果您没有权限,请查看您的DBA是否允许您访问将执行截断的存储过程。

作为最后的替代方案,我建议使用事务和绑定变量。这两种方法都可以通过普通的ADO命令(无bcp)显着提高插入速度。我想如果你测试bcp,你可能不想做任何其他事情。

答案 1 :(得分:1)

费用部分是连接上的往返,因此请尝试在每个execute上发送多个插入

创建一个计数器变量i,每次插入10行

 Do Until .Cells(RowNo, 1) = "" 
     i = i+1;

将命令保存在字符串中,用分号;

分隔每条指令
strSQL = strSQL + "insert into EcommerceTablename ([Col_1_C], [Col_2_C], [Col_3_C], [Col_4_C]) values ('" & C1 & "', '" & C2 & "', '" & C3 & "', '" & C4 & "');"

每次执行10次插入。

if i mod 10 = 0 then
   conn.Execute strSQL
循环结束后

插入剩余的行。

loop
conn.Execute strSQL

答案 2 :(得分:-1)

Range("A1").Select

 Dim conn As New ADODB.Connection
    Dim iRowNo As Integer
    Dim sFirstName, sLastName As String

    With Sheets("Sheet1")

        'Open a connection to SQL Server
        conn.Open "Provider=SQLOLEDB;Data Source=SWD-03\SQLEXPRESS;Initial Catalog=PDS_Testing;User ID=Sa;password=pass.123;"

        'Skip the header row
        iRowNo = 2

        'Loop until empty cell in CustomerId
        Do Until .Cells(iRowNo, 4) = ""
        sPartno = .Cells(iRowNo, 4)
        sBatchID = .Cells(iRowNo, 5)
        sDimension = .Cells(iRowNo, 6)

            'Generate and execute sql statement
            ' to import the excel rows to SQL Server table
   conn.Execute "IF NOT EXISTS (SELECT 1 FROM dbo.Project1 WHERE ID = '" & sID & "' ) " & _
         "INSERT INTO dbo.Project1 (Partno  ,BatchID ,Dimension) " & _
         "VALUES ('" & sPartno & "', '" & sBatchID & "','" & sDimension & "' )"

            iRowNo = iRowNo + 1
        Loop
        MsgBox "Saved Sucessfully."
        conn.Close
        Set conn = Nothing
    End With

答案 3 :(得分:-1)

Sub Button14_Click()
Range("A1").Select

 Dim conn As New ADODB.Connection
    Dim iRowNo As Integer
    Dim sFirstName, sLastName As String

    With Sheets("Sheet1")

        'Open a connection to SQL Server
        conn.Open "Provider=SQLOLEDB;Data Source=SWD-03\SQLEXPRESS;Initial Catalog=PDS_Testing;User ID=Sa;password=pass.123;"

        'Skip the header row
        iRowNo = 2

        'Loop until empty cell in CustomerId
        Do Until .Cells(iRowNo, 4) = ""
        sPartno = .Cells(iRowNo, 4)
        sBatchID = .Cells(iRowNo, 5)
        sDimension = .Cells(iRowNo, 6)

            'Generate and execute sql statement
            ' to import the excel rows to SQL Server table
   conn.Execute "IF NOT EXISTS (SELECT 1 FROM dbo.Project1 WHERE ID = '" & sID & "' ) " & _
         "INSERT INTO dbo.Project1 (Partno  ,BatchID ,Dimension) " & _
         "VALUES ('" & sPartno & "', '" & sBatchID & "','" & sDimension & "' )"

            iRowNo = iRowNo + 1
        Loop
        MsgBox "Saved Sucessfully."
        conn.Close
        Set conn = Nothing
    End With


End Sub