简体   繁体   English

MS Access Insert into Slow for Large Recordset (VBA)

[英]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 .而是使用带有.AddNewDAO.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM