使用 VB 写入大量记录以访问

Posted

技术标签:

【中文标题】使用 VB 写入大量记录以访问【英文标题】:Writing Large Amounts of Records to Access using VB 【发布时间】:2012-08-15 22:58:24 【问题描述】:

我目前正在 Visual Studio 中编写一些软件,以使用 SQL 分析来自 Access 数据库的大量数据。我有代码来创建一个新的计算变量,但我正在为将数据写回 Access 所花费的时间而苦苦挣扎。

我目前正在使用一些 vb com 代码与我的 Access 数据库进行通信,该数据库在 2002/3 比较模式下运行。以下是我当前的代码,它在循环中运行一个函数来写入数据库。

cnnOLEDB = New OleDbConnection
    cnnOLEDB.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & DataDirectoryName & DatabaseFileName
    cnnOLEDB.Open()

    'cmdOLEDB = New OleDbCommand
    cmdOLEDB.Connection = cnnOLEDB

    ColumnString = "ID_VAR, ID_PAR, TimeValue, strValue, ID_UPL"
    For RecordCounter = 0 To CalcData.GetLength(1) - 1
        Var_ID = Var_ID + 1
        ValueString = Format(Var_ID, "0") & ", " & Format(Parameter, "0") & ", #" & Date2String(CDate(CalcData(0, RecordCounter))) & "#, " & CalcData(CalcData.GetLength(0) - 1, RecordCounter) & ", " & Format(AsUpload, "0")
        If DatabaseConnectionInsert("INSERT INTO " & TableName & " (" & ColumnString & ") VALUES (" & ValueString & ")", "Non-Query") = "Error" Then GoTo Close
    Next

    cnnOLEDB.Close()

这里是函数:

Public Function DatabaseConnectioninsert(ByVal Query As String, ByVal Task As String) As String
        'On Error GoTo Err

        'If cnnOLEDB.State = ConnectionState.Open Then cnnOLEDB.Close()
        cmdOLEDB.CommandText = Query

        Select Case Task
            Case "Read Recordset"
                rdrOLEDB = cmdOLEDB.ExecuteReader()
                DatabaseConnectioninsert = "Read Recordset"
            Case "Read Scalar"
                DatabaseConnectioninsert = cmdOLEDB.ExecuteScalar
            Case "Non-Query"
                cmdOLEDB.ExecuteNonQuery()
                DatabaseConnectioninsert = "Non-Query"
        End Select

        Exit Function
Err:
        MsgBox("Database connection error.")
        DatabaseConnectioninsert = "Error"


    End Function

我目前正在尝试为每个参数将 ~4500 条记录插入 Access 数据库,这需要 ~3 分钟。但是,当项目上线时,每个参数必须处理超过 100000 条记录,因此速度还不够快。

为了解决这个问题,我正在考虑将我的代码更新为 .net 或创建一个记录集,这样我就可以一次移动 Access 中的所有数据。谁能给我一些建议,哪些对提高插入速度的影响最大。我正在运行 Visual Studio 2005 和 Access 2007,将数据库更新到 2007 而不是兼容模式是可能的,但并不理想,但是我当前的代码无法访问它。

感谢您的帮助

乔什

【问题讨论】:

您确定将 Access 用于必须以合理的时间方式处理数十万条记录的数据库应用程序是一个合理的技术决策吗? 在我看来 Access db 是在分析工作中继承的东西 :) @Pezzzz,我对 Access 的详细了解相当有限,但我至少会鼓励您看看是否可以进行批量插入(例如,避免每次插入时提交),或者也许,作为一种完全替代的方法,将新数据生成为文本文件,然后单独导入文本文件。我认为,当您开始记录数十万条记录时,Access 将成为越来越不受欢迎的数据库解决方案。 不只是 Access,这是 RBAR,几乎可以杀死任何数据库。 SQL Server 或 SQL Server Compact Edition 可能是不错的选择。我知道,后者比 Access 快得多。 【参考方案1】:

听起来很荒谬,在 Access 数据库上获得的最佳性能是使用 ancient DAO COM 库。使用RecordSet 对象在循环中一次添加一条记录,并通过它们的索引(序数位置)而不是它们的名称来引用这些字段。你会发现它比使用oleDB.ExecuteNonQuery 快得多,得多

请参阅the solution given here 了解更多信息。它是 C#,但如果您想尝试一下,它很容易遵循并转换为 VB.NET。

编辑 尊重以下 Remou 的 cmets:看起来 Microsoft 已经实际上一直在保持 DAO 技术的最新状态——尽管早在 2002 年就有declaring it obsolete——但你必须使用Office Access Redistributable 而不是比更知名的 DAO 3.6 库。

【讨论】:

DAO 并不古老,它一直在开发中,并在 2010 年发布了新版本。但是,问题在于 RBAR 方法,它不会很快。 @Remou 你确定你不考虑 ADO 吗? AFAIK,DAO 的最后一个版本是 3.6——我相信它是随 Office 2000 和 VS6 的 SP6 发布的。从那时起,该 DLL 可能已经有了一些小的安全修复,但早在 2002 年就没有重大更新和 MS declared it obsolete。 最新的是Microsoft Office 12.0 Access Database Engine Object Library 至于它是 RBAR:当然,您是对的,但是我链接的解决方案的时序图表明,使用 DAO 可以比其他方法获得显着的性能提升。它比使用 OLEDB 表适配器快 30 倍。 它可以免费下载microsoft.com/en-us/download/details.aspx?id=13255,并显示在我的com列表中。它是自 2007 年以来分发的 DAO 的更新版本。Jet 已弃用但仍在使用,ACE 不是,DAO 也不是。

以上是关于使用 VB 写入大量记录以访问的主要内容,如果未能解决你的问题,请参考以下文章

VB.NET 访问 - 试图读取或写入受保护的内存

VB.NET 访问日期时间查询问题

从 vb.net 中的访问中计算特定记录

从 ms 访问数据库读取以使用 vb 显示在表单上

VB.Net 向 SQLite-DB 写入大量数据

如何通过vba查看访问表中的记录集?