将完整的 ADO 记录集插入现有的 ACCESS 表而不使用循环

Posted

技术标签:

【中文标题】将完整的 ADO 记录集插入现有的 ACCESS 表而不使用循环【英文标题】:insert full ADO Recordset into existing ACCESS table WITHOUT LOOP 【发布时间】:2015-12-25 14:44:20 【问题描述】:

我的 VBA 模块中有一个填充的 ADO 记录集。我在 ACCESS 中也有一个与记录集结构完全相同的表。

现在我使用循环(这很好)遍历每个数据集记录来填充表格。

我想知道的是:有没有办法将整个记录集插入到访问表中? (更重要的是:这会明显更快)

【问题讨论】:

【参考方案1】:

这是一个基本示例(在本例中从 excel 运行),说明使用断开连接的记录集添加记录。

Sub Tester()

    Dim con As ADODB.Connection, rs As ADODB.Recordset
    Dim i As Long

    Set con = getConn()

    Set rs = New ADODB.Recordset
    rs.CursorLocation = adUseClient '<<<< important!

    'get an empty recordset to add new records to
    rs.Open "select * from Table1 where false", con, _
             adOpenDynamic, adLockBatchOptimistic

    'disconnect the recordset and close the connection
    Set rs.ActiveConnection = Nothing
    con.Close
    Set con = Nothing

    'add some new records to our test recordset
    For i = 1 To 100
        rs.AddNew
        rs("UserName") = "Newuser_" & i
    Next i

    'reconnect to update
    Set con = getConn()
    Set rs.ActiveConnection = con

    rs.UpdateBatch '<<< transfer to DB happens here: no loop!

    rs.Close 

    'requery to demonstrate insert was successful
    rs.Open "select * from Table1", con, _
            adOpenDynamic, adLockBatchOptimistic

    Do While Not rs.EOF
        Debug.Print rs("ID").Value, rs("UserName").Value
        rs.MoveNext
    Loop

    rs.Close
    con.Close
End Sub

Function getConn() As ADODB.Connection
    Dim rv As New ADODB.Connection
    Dim strConn As String

    strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" _
     & "Data Source = " & ThisWorkbook.Path & "\Test.accdb"

    rv.Open strConn
    Set getConn = rv
End Function

【讨论】:

谢谢,我用了类似的东西。问题是如何避免必须使用循环,而只需将整个记录集转储到表中,就像您可以在两个访问表之间执行的操作一样 (SELECT * INTO SomeTable FROM SomewhereElse) 但仍然很有用! 我唯一的循环是加载测试记录集并在更新后显示结果。数据加载全部发生在单个UpdateBatch 行中。你指的是什么循环? 糟糕,我意识到我错过了最重要的部分。但我现在明白了。这就是我希望找到的。非常有帮助,感谢您的澄清 @tim 很奇怪,我认为您的回答实际上并没有回答这个问题。当然,这是关于建立一个记录集,然后将其放回不同的或任何!桌子。 Parfait 的回答概述了一种方法,您对此有何看法。你的回答把它放回了它来自的表中(这将涵盖 99.9% 的场景,包括 OP 的场景!) @HarveyFrench - OP 的问题开始于“我有一个已填充的 ADO 记录集”,所以在我看来问题不是关于 填充 记录集,而是关于如何将那些记录从 OP 已经拥有的记录集中插入到表中而不循环。我发布的代码是使用UpdateBatch 方法执行此操作的示例。由于 OP 没有发布任何与创建他们的记录集相关的代码,而且我感到很懒惰,我使用从目标表中选择的“无记录”创建了我的 example 记录集,以确保字段匹配正是。【参考方案2】:

VBA 记录集实际上存在于运行时调用的内存中,直到它们包含在保存到硬盘上的实际物理格式(即 csv、txt、xlsx、xml、数据库临时表)中。这类似于 R 或 Python pandas、SAS 数据集、php 数组和其他数据结构中的数据帧。

考虑使用CopyFromRecordset 方法将您的ADO 以这种格式导出到Excel 电子表格中,以保存为csv、txt、xlsx 或xml。或者,您可以使用Save 方法将记录集保存为持久格式类型,例如 xml。

然后,使用其自动数据迁移功能将结果文件附加到 MS Access 表中:

对于电子表格:DoCmd.TransferSpreadsheet 对于 txt、csv 或其他分隔文件:DoCmd.TransferText 对于 xml 文件:Application.ImportXML 对于本地或 ODBC/OLEDB 链接数据库表:INSERT INTO 附加 SQL 查询

【讨论】:

ADO 到 Excel 到 Access。听起来它会比循环 INSERT 语句更快。遗憾的是,您不能使用 SELECT 语句从记录集(或者可能是数组......嗯。值......【参考方案3】:

没有。没有反向等价物 - 可能是 SetRows - 方法 GetRows

【讨论】:

【参考方案4】:

要使用 SQL 语句完成此操作,请使用 SELECT/INSERT... IN [Designate DB A;记录张贴到] 或 FROM... IN [指定 DB B;记录原始出处]

您只能在单个查询中使用一次 IN 语句。因此,您使用 ADODB 连接来创建其他连接以确定其他源连接。

Function example()
Dim dB_External As String
Dim db_Local As String
Dim cnLocal As ADODB.Connection
Dim cnExternal As ADODB.Connection

Set cnLocal = CurrentProject.Connection
Set cnExternal = New ADODB.Connection
cnExternal .Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\\...accdb;Persist Security Info=False;"

dB_External = "C:\Users\\...accdb"
db_LOCAL = "C:\Users\\...accdb"

Example A:
strSQL = "INSERT INTO *Local table to receive records* (Column Designations)"
strSQL = strSQL & " SELECT ( *Corresponding records from external table* )"
strSQL = strSQL & " FROM *External table name* IN '" & dB_External & "'"
cnLocal.Execute (strSQL)

如果我从单个外部表中选择,我使用上面的代码和本地 ADODB 连接。

Example B:
strSQL = "INSERT INTO *Local table to receive records* (Column Designations) IN '" & dblocal & "'"
strSQL = strSQL & " ( *Corresponding records from external table* )"
strSQL = strSQL & " FROM *External table name*
cnExternal.Execute (strSQL)

我使用上面的代码使用外部 ADODB 连接,如果我选择涉及连接外部数据库中的多个表。

【讨论】:

以上是关于将完整的 ADO 记录集插入现有的 ACCESS 表而不使用循环的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ADO 记录集字段将图片加载到 MS-Access Image 控件中?

MS Access ADO 记录集和二维数组

为啥 ADO 记录集返回的记录比基础 Access 查询多

MS Access - ADO 记录集,使用 SQL 语句检索数据和建表

将 DAO 记录集转换为断开连接的 ADO 记录集 dbDecimal 问题

在没有记录集循环的情况下使用 ado 和 vbscript 从 csv 更新数据库?