MS Access MDB-File不断损坏

时间:2018-01-23 11:33:57

标签: vba ms-access jet

我们遇到了Microsoft Access .mdb文件的问题。在多用户环境中使用.mdb文件一段时间后,该文件已损坏并且必须进行修复。修好之后,再次损坏需要更少的时间。并且在多次重复之后的某个时刻,该文件不再可用。

我们从MS Access Runtime 2010更改为MS Access Runtime 2013后,此问题开始出现。

我已经花了一些时间研究这个问题,这是我的理论:

mdb文件显然包含"数据库标题页" (在Microsoft的白皮书中称为"了解Microsoft Jet Locking"从1996年开始),它保存了有关用户提交字节的信息(重要:0000 =写入磁盘,0100 =访问损坏的页面)。白皮书中有一个关于此数据库页眉页面的段落,它解释了我们的问题中究竟发生了什么:

" [...]因此,如果在没有相应的用户锁定的情况下存在00 00的值[这将是我认为相应的.ldb文件中的条目],或者存在值0100 ,如果没有首先执行修复实用程序,将不允许用户连接到数据库。"

所以我的猜测是,在与mdb失去连接并断开连接之后,此数据库标题页溢出并且您必须修复该文件但修复不会删除此数据库标头内的每个条目Page,因此文件损坏所需的断开连接数量会减少,直到文件完全中断为止。

现在我想知道这个理论是否有用,如果是的话我想知道:

  1. 如何测试此理论(如何阅读mdb文件的此数据库页眉)?

  2. 我可以修改数据库标题页吗?

  3. 我可以在有人使用mdb时修改数据库页眉吗?

  4. 我知道这是一个非常具体的问题,但我希望你们能帮助我!

    P.S。我无法找到白皮书的链接,但是" LDBViewer" -packet包含此白皮书。

1 个答案:

答案 0 :(得分:0)

我经常使用的一些快速而肮脏的技巧是通过创建一个用于一个目的的小型数据库来实现的:控制所需目标数据库的打开方式。 此数据库被复制到每个用户的桌面,因此每个用户/会话都有自己的。

所以我会有 *服务器位置上的1个数据库:$_ -replace '(?<=^\[tag2\] = ).*'
* 1数据库已复制到多个桌面:[TheBigOne.mdb]

- 01--: 每天早上,调用一个函数,它将执行以下步骤: [TheCaller.mdb]


--02-- 使用一个按钮* rename [TheCaller.mdb] to [TheCaller-xxx.mdb] * create and open [TheCaller-NEW.mdb] * for all tables, queries, forms, reports, macros, modules DoCmd.TransferDatabase acImport, , [TheCaller-xxx.mdb], _ acTable-acQuery-acForm-acReport-acMacro-acModule, "y", "y", False * rename [TheCaller-NEW.mdb] to [TheCaller.mdb] [TheCaller.mdb]创建一个表单,其中包含OnClick - 事件,例如:
If Dir(ServerLocation & "\TheBigOnd.ldb") = "" Then
    'open [TheBigOne.mdb]
Then
    Msgbox "Database already in use!"
End If
这很容易让人头疼,因为[TheBigOnd.ldb]文件确实存在,而没有人使用数据库。但至少,您将减少数据库损坏。

- 03 - 可以使用命令行开关/excl来实现此过程的替代方法--02--。在任何给定时间,只有一个用户可以在数据库中工作。

- 04 - 在表单上创建第二个按钮--02--,它将使用命令行开关[TheBigOne.mdb]打开/ro。这将为该用户以只读模式打开数据库,避免数据库损坏。

- 05-- 在服务器位置创建一个小的后端数据库db_sessions.mdb 其中包含T_Sessions(id, whois, started_at_timestamp, ended_at_timestamp, excl_or_ro, troubles)的表格,用于跟踪[who] [打开]和[关闭] [何时]数据库[TheBigOne.mdb]
如果用户想要更多权限然后只读,则必须进行以下测试:DCount("*","T_Sessions","ended_at_timestamp is null AND excl_or_ro = 'excl'") = 0。如果此测试结果为false,则可以使用字段troubles将消息发送给其他用户。