检测断开连接的Microsoft Access链接表

时间:2013-04-10 15:59:17

标签: ms-access ms-access-2007

最重要的是,我希望尽可能优雅地处理网络断开连接。

我有一个Microsoft Access应用程序,它使用链接表将UI与数据“分开”。因此,有两个msaccess数据库文件(一个UI和其他数据)。这两个数据库都在我们的内部网络上,UI使用链接表链接到数据。这是一个非常标准的设置。

代码中只有一个位置我想要这个优雅的断开连接逻辑(在执行SQL UPDATE时)。我认为它会像一些错误处理一样简单。但是, Microsoft Access有时会假装成功

这是进入我世界的窗口:

On Error GoTo ErrorHandler:
Call CurrentDb.Execute("UPDATE [Thing] SET [Length]=5 WHERE [ID]=1;", dbFailOnError)
On Error GoTo 0

   ...(continued code)...

ErrorHandler:
    fSuccess = False
    Resume Next

我启动应用程序,拔掉我的网络电缆(不,wifi没有打开),但有时候错误处理永远不会发生,即使它实际上没有更新!为了澄清,断开连接时,我希望此更新失败,我想检测它!

我一直试图解决这样对我说谎的问题。我尝试的越多,我就越绝望:

  1. 我注意到的第一件事就是如果我逐步使用调试器,它将正确且可靠地失败。但这对我没有帮助。
  2. 我尝试检查更新操作的 RecordCount ,但是当它假装成功时,它确实设置为1!
  3. 我尝试过后续的SELECT语句来查看UPDATE是否真的发生了。尽管如此,即使我在UPDATE中放入一个随机数字,访问也会返回正确的结果。
  4. 我查看了Access对象(如CurrentDb和TableDefs),寻找任何可靠的指示,表明它正在“离线模式”或“缓存模式”下工作。我找不到任何指标。这对我有很大帮助。
  5. 链接表的RecordCount始终为-1,无论是连接还是断开连接。
  6. 通过修改和修复“Connect”连接字符串,断开连接并重新连接相关的TableDef。访问声称它重新连接正常。
  7. 我不明白我所看到的行为。 MSAccess是否在连接数据的某些缓存下运行?如果是这样,为什么它只有有时?如果他们真的有一些复杂的离线缓存模式,为什么它没有记录在任何地方?不幸的是,我不允许在工作时喝酒。

4 个答案:

答案 0 :(得分:1)

我从来没有像你描述的那样出现问题,但我做了两件事:

  1. 我总是声明Dim cdb As DAO.DatabaseSet cdb = CurrentDB,然后执行cdb.Whatever。有时候CurrentDB.Whatever的行为会有所不同。

  2. 我总是cdb.Execute "SQL statement", dbFailOnError。我认为这可能与您的问题特别相关。

答案 1 :(得分:1)

或许,正如您所建议的那样,db引擎对内存中存在的UPDATE表的缓存版本执行[Thing],以便稍后将其写入磁盘。但是,如果这是正在发生的事情,似乎Access应该在以后尝试执行磁盘写入时抛出错误。

老实说,我不明白为什么你没有收到错误。我认为在事务和use dbForceOSFlush with CommitTrans中尝试UPDATE可能会有用。至少它可能会强制一个错误,你的代码可以在你遇到这个问题时知道它。

Dim strUpdate As String
Dim db As DAO.Database
Dim ws As DAO.Workspace

strUpdate = "UPDATE [Thing] SET [Length]=5 WHERE [ID]=1;"
Set ws = DBEngine(0)
Set db = CurrentDb
ws.BeginTrans
db.Execute strUpdate, dbFailOnError
ws.CommitTrans dbForceOSFlush
ws.Close
Set db = Nothing
Set ws = Nothing

答案 2 :(得分:0)

到目前为止,我提出的最好的方法是检查我是否可以访问底层数据库文件。

Public Function EnsureNetworkConnected() As Boolean

    Dim sDataPath As String
    sDataPath = GetDataPath

    Dim fFileExists As Boolean
    Dim objFileSystem As New FileSystemObject
    fFileExists = objFileSystem.FileExists(sDataPath)
    If Not fFileExists Then
        ' Huh.
    End If

    EnsureNetworkConnected = fFileExists

End Function

如果更新语句“假装”成功,我会使用此函数仔细检查它。这是一个脆弱的黑客。

如果您遇到问题并打算使用此解决方案,则使用 GetDataPath 函数通过 CurrentDb.TableDefs

获取链接表的位置

答案 3 :(得分:0)

我意识到这个线程有点陈旧,但我现在陷入了与描述相同的情况,并希望加上我的两个便士。

我添加了" dbForceOSFlush"正如HansUp上面所建议的那样。当我移除网络电缆(并关闭WiFi)时,我仍然没有收到错误

Dim wrk As DAO.Workspace
Dim dbs As DAO.Database
Set wrk = DBEngine(0)
Set dbs = CurrentDb
wrk.BeginTrans
dbs.Execute "aJudges", dbFailOnError
wrk.CommitTrans dbForceOSFlush
Debug.Print "AppendJudger " & Time()
TimerCounter = 0

另一个观察是,当我拉网络时,第一次执行查询的尝试需要很长时间(比如30秒),之后所有查询都会平滑运行,只是连接丢失,因此关闭Access时会丢失任何数据。