2013-04-10 107 views
2

底线是我想尽可能优雅地处理网络断开连接。检测断开连接的Microsoft Access链接表

我有一个Microsoft Access应用程序使用链接表将数据从使用链接表的数据“分开”。所以,有两个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 

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

我一直在试图解决Access这样对我说谎。我试过的越多,越绝望的我已经成为:

  1. 的第一件事情,我注意到的是,如果我与调试器步将正确可靠失败。虽然这对我没有帮助。
  2. 我试过检查更新操作的RecordCount,但是当它假装成功时,它确实设置为1!
  3. 我试着做一个后续的SELECT语句来查看UPDATE是否真的发生了。尽管如此,即使我在UPDATE中放入了一个随机数,访问也会返回正确的结果。
  4. 我已经通过Access对象(如CurrentDb和TableDefs)寻找任何可靠的指示,表明它正在“脱机模式”或“缓存模式”下工作。我找不到任何指标。这对我很有帮助。
  5. 无论连接还是断开,链接表的RecordCount始终为-1。
  6. 我有断开并重新连接关联的TableDef通过修改和修复“连接”连接字符串。访问声称它重新连接好。

我不明白我看到的行为。 MSAccess是否在连接数据的某个缓存下运行?如果是这样,为什么它只能工作有时?如果他们真的有一些复杂的离线缓存模式,为什么没有记录在任何地方?不幸的是,我不允许在工作时喝酒。

+0

+1为您的最后一句话。 (但是,问题的其余部分也值得+1。) – 2013-04-10 17:24:34

+0

您是否使用'dbFailOnError'参数? – Scotch 2013-04-10 19:41:27

+0

是的。对不起,我不清楚,我简化了这个例子,因为完整的代码有点麻烦。 – 2013-04-11 20:15:51

回答

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 

如果update语句“pretends”成功,我使用这个函数仔细检查它。这是一个脆弱的黑客。

如果你有我的问题,并打算使用此解决方案,使用的GetDataPath功能通过CurrentDb.TableDefs获取链接表的位置

1

我从来没有完全像你描述一个问题,但我做两分不同的事情:

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

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

+0

感谢您的想法。我已经在做这两件事,但为了简单起见,我被骗了。 – 2013-04-10 18:11:12

1

也许,如你所说,数据库引擎执行UPDATE针对存在于您的[Thing]表中的缓存版本,以便稍后将其写入磁盘。但是,如果发生这种情况,Access似乎会在尝试执行磁盘写入时稍后发出错误。

老实说,我不明白你为什么没有得到一个错误。我认为在交易中尝试UPDATEuse dbForceOSFlush with CommitTrans可能很有用。至少它可能会强制一个错误,当你有这个问题时,你的代码可以捕捉到这个错误。

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 
+0

这是一个好主意。我没有意识到这个冲动的想法。我会尽力而为。目前,我的黑客检查网络访问目前已到位,并且很难重新创建。 – 2013-04-18 18:44:31

0

我意识到这个线程是有点老,但现在我抓到在同样的情况描述,并希望增加我的两个便士。

我添加了上面HansUp建议的“dbForceOSFlush”。不过,当我删除我的网线(而且无线的转)

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时会丢失任何数据。