[英]MS Access Insert Into Slow for Large Recordset (VBA)
I have a section of code which creates a new table and then attempts to copy the record set values into the table.我有一段代码创建一个新表,然后尝试将记录集值复制到表中。 The only problem is this it is quite slow and access shows the loading symbol whilst it is executing this insert section below.唯一的问题是它很慢,并且访问在执行下面的插入部分时会显示加载符号。 Currently this problem is occurring inserting 500 records, but I will need to insert around 10,000 to 20,000 when I get a final data set.目前这个问题是在插入 500 条记录时发生,但是当我获得最终数据集时,我需要插入大约 10,000 到 20,000 条记录。
I = 1
DoCmd.SetWarnings False
RecordSet1.MoveFirst
Do While Not RecordSet1.EOF = True
SQL = "INSERT INTO " & FullName & " ("
For Each field In RecordSet1.fields()
SQL = SQL & " " & Replace(field.Name, ".", "_") & ","
Next field
SQL = SQL & "ValidationCheck)"
SQL = SQL & " VALUES("
For Each field2 In RecordSet1.fields()
SQL = SQL & "'" & field2.Value & "',"
Next field2
SQL = SQL & Matches(I) & ")"
DoCmd.RunSQL (SQL)
RecordSet1.MoveNext
I = I + 1
Loop
What I want to know is, is there any way I can speed this up?我想知道的是,有什么办法可以加快速度吗? Or are there better approaches?或者有更好的方法吗? (What I am trying to do is create a table at run time with a unique set of fields from a RecordSet and add an extra column with a Boolean value stored in Match array for each Record). (我想要做的是在运行时创建一个表,其中包含来自 RecordSet 的一组唯一字段,并添加一个额外的列,其中包含存储在每个记录的 Match 数组中的布尔值)。 The creation works fine, but the insertion code above is very slow.创建工作正常,但是上面的插入代码很慢。
Yes, use DAO.是的,使用 DAO。 So much faster.快得多。 This example copies to the same table, but you can easily modify it so copy between two tables:此示例复制到同一个表,但您可以轻松修改它,以便在两个表之间复制:
Public Sub CopyRecords()
Dim rstSource As DAO.Recordset
Dim rstInsert As DAO.Recordset
Dim fld As DAO.Field
Dim strSQL As String
Dim lngLoop As Long
Dim lngCount As Long
strSQL = "SELECT * FROM tblStatus WHERE Location = '" & _
"DEFx" & "' Order by Total"
Set rstInsert = CurrentDb.OpenRecordset(strSQL)
Set rstSource = rstInsert.Clone
With rstSource
lngCount = .RecordCount
For lngLoop = 1 To lngCount
With rstInsert
.AddNew
For Each fld In rstSource.Fields
With fld
If .Attributes And dbAutoIncrField Then
' Skip Autonumber or GUID field.
ElseIf .Name = "Total" Then
' Insert default value.
rstInsert.Fields(.Name).Value = 0
ElseIf .Name = "PROCESSED_IND" Then
rstInsert.Fields(.Name).Value = vbNullString
Else
' Copy field content.
rstInsert.Fields(.Name).Value = .Value
End If
End With
Next
.Update
End With
.MoveNext
Next
rstInsert.Close
.Close
End With
Set rstInsert = Nothing
Set rstSource = Nothing
End Sub
For multiple inserts in a loop, don't use SQL INSERT statements.对于循环中的多个插入,不要使用 SQL INSERT 语句。 Instead use a DAO.Recordset
with .AddNew
.而是使用带有.AddNew
的DAO.Recordset
。
See this answer: https://stackoverflow.com/a/33025620/3820271看到这个答案: https : //stackoverflow.com/a/33025620/3820271
As positive side effects, your code will become better readable and you don't have to deal with the multiple formats for different data types.作为积极的副作用,您的代码将变得更好可读,并且您不必处理不同数据类型的多种格式。
For Each field In RecordSet1.Fields
rsTarget(field.Name) = field.Value
Next field
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.