我有一个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
答案 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>
据我所知,我列出的选项是:
此外,如果您对表有权限,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