不断增长的MS Access文件大小问题

时间:2009-01-16 16:24:44

标签: database ms-access

我有一个大型MS Access应用程序,在VBA代码中有很多计算。当我运行它时,它最终会因文件过大而崩溃。创建并随后删除了许多中间表和查询,但Access不会回收空间。我已经努力关闭所有中间记录集并将所有临时对象设置为空,但没有任何帮助。我可以运行代码的唯一方法是运行部分代码,停止并修复/压缩文件,然后重新启动代码。

有没有更好的方法?

由于

9 个答案:

答案 0 :(得分:9)

您应该能够在VBA代码中运行compact函数。

我在很久以前做过访问工作时收到了下面的代码片段。

Public Sub CompactDB() 
    CommandBars("Menu Bar").Controls("Tools").Controls("Database utilities").Controls("Compact and repair database...").accDoDefaultAction 
End Sub 

你可以把它放在你的代码中来解决它。

注意:如果您遇到这些类型的扩展问题,您可能还会考虑扩展到更大的数据库系统。

答案 1 :(得分:3)

您要处理的尺码是多少?它崩溃时的错误代码是什么?如果只是因为文件“太大”我会感到惊讶,但我想有一个限制。从你对所有临时材料的描述中可以看出,设计改进可能有所帮助。

编辑:我希望你意识到用其他东西替换数据库是非常重要的 - 即使你试图保留除了表之外的mdb中的其他内容。访问querydef是唯一的,Access SQL是非标准的,你基本上就是重新开始。

我见过的大多数Access应用程序都有很多重构的机会;如果a)您理解逻辑和业务规则,并且b)您对Access编程有扎实的理解,通常并不困难。但对于任何替代品来说,这或多或少都是正确的。如果我是你,你在这两个领域都有点短暂,也许你可以得到一些帮助。但我首先尝试抢救Access应用程序。

另一张海报也提出了关于将表格移动到一个或多个附加MDB中的建议。这是一种坚实的,经过充分验证的技术。但首先,我要了解问题的真正原因。

答案 2 :(得分:2)

我将数据推送到MS SQL(永久数据和中间表);并且您可以暂时将代码部分保留在MS Access中。

这解决了两个大问题:

  1. 数据本质上更稳定/可靠(我不能告诉你有多少次我有一个损坏的MS Access数据库)。
  2. 您的Access数据库不会发生太大的变化(一旦运行和编译完所有代码,它就会达到平衡)。
  3. 这两个意味着不再需要压缩/修复数据库;你可以获得MS SQL的免费版本(Express Edition),这并不难。

答案 3 :(得分:1)

如果您不想切换到SQL Express或类似产品,可以挖掘以下想法:

  • 为所有临时表打开另一个“外部”访问数据库(mdb文件),这样您就可以将所有临时数据放在外部文件中,在关闭应用程序时丢弃mdb文件。然后,您将在代码中操作'currentDb'对象和您在启动时构建的另一个数据库,并通过jet,OLEDB或ODBC连接进行连接
  • 将永久表与代码分开,并在需要时将数据带入本地客户端界面以构建临时表。这可以通过使用“DoCmd.transferDatabase acLink”将外部数据库链接到本地​​/客户端文件来完成。这也可以通过OLEDB连接连接到永久数据,打开所需的记录集并将它们作为XML文件保存在本地来完成。这里可以实现许多其他解决方案。

答案 4 :(得分:0)

答案 5 :(得分:0)

不幸的是,当你变得太大时,MS Access会出现问题 - 我认为访问数据库的最大大小为2GB。

您可以考虑迁移到Sql Express,VistaDB等。

答案 6 :(得分:0)

根据http://office.microsoft.com/en-us/access/HP051868081033.aspx,Access 2003和2007的限制为2 GB。但是,将一些或所有表移动到单独的.mdb文件中然后链接到这些表很容易。无论如何,最好有两个文件,一个用于数据,一个用于所有宏,查询等。如果表文件接近2 GB限制,您甚至可以拥有多个文件。

答案 7 :(得分:0)

关于Jet文件大小的事态对我来说是无可争议的问题。

我目前正在从Access数据库A看一块我自己的VBA代码,因为它使用ADO对Access数据库B上的表进行了一系列单记录字段更新(通过可更新 - 数据库A)中的查询引用。单个字段是CHAR(8)。随着每4次更新,数据库B增长约8千字节。没有好借口。文件大小的增加会严重降低性能;随着每个文件的增长,更新速度从大约每秒一个(在使用单记录SQL查找的大约30-40K记录的表中,并且在任何地方没有索引)到每5-10秒一个。 现在,我承认,在运行此更新代码之前,我确实压缩/修复了数据库B.也许如果我没有这样做,表现就不会那么糟糕。如果更新的目标字段是,例如,键入备注,那么我会预料到这一点。但是要在CHAR()字段上执行更新并获得此结果是不合理的。

上述大部分内容(对任何一个解决方案没有特别的批评)似乎是使用相对永久的业务应用程序安排的应用程序的有效解决方案(始终与相同的目标数据库通信)。我不是这样。 。 。我无法更改目标数据库(数据库B),因为它是由我们用于从其应用程序导出和导入数据的供应商工具生成和使用的。

我理解并赞扬上述作者提出解决用户问题的方法。但是,当不良软件设计/实现妨碍用户使用产品时,我无法忍受它,因为用户期望它能够正常运行。

答案 8 :(得分:0)

我遇到了类似的问题,我的数据库在原始数据导入时膨胀。我决定使用数据库对象(DAO)创建临时数据库,导入数据,查询/修改临时数据库中的数据,通过SQL将其拉到原始数据库,而不是分割数据库并定期压缩后端。然后删除它。 YBase代码如下所示:

Sub tempAccessDatabaseImport()
    Dim mySQL As String
    Dim tempDBPath As String
    Dim myWrk As DAO.Workspace
    Dim tempDB As DAO.Database
    Dim myObject

    'Define temp access database path
    tempPathArr = Split(Application.CurrentProject.Path, "\")
    For i = LBound(tempPathArr) To UBound(tempPathArr)
        tempDBPath = tempDBPath + tempPathArr(i) + "\"
    Next i
    tempDBPath = tempDBPath + "tempDB.accdb"

    'Delete temp access database if exists
    Set myObject = CreateObject("Scripting.FileSystemObject")
    If myObject.FileExists(tempDBPath) Then
        myObject.deleteFile (tempDBPath)
    End If

    'Open default workspace
    Set myWrk = DBEngine.Workspaces(0)

    'DAO Create database
    Set tempDB = myWrk.CreateDatabase(tempDBPath, dbLangGeneral)

    'DAO - Import temp xlsx into temp Access table
    mySQL = "SELECT * INTO tempTable FROM (SELECT vXLSX.*FROM [Excel 12.0;HDR=YES;DATABASE=" & RAWDATAPATH & "].[" & WORKSHEETNAME & "$] As vXLSX)"

    'DAO Execute SQL
    Debug.Print mySQL
    Debug.Print
    tempDB.Execute mySQL, dbSeeChanges

    'Do Something Else

    'Close DAO Database object
    tempDB.Close
    Set tempDB = Nothing

    myWrk.Close
    Set myWrk = Nothing

    'Delete temp access database if exists
    If myObject.FileExists(tempDBPath) Then
        'myObject.deleteFile (tempDBPath)
    End If
End Sub