检测断开连接的Microsoft Access链接表
底线是我想尽可能优雅地处理网络断开连接。检测断开连接的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这样对我说谎。我试过的越多,越绝望的我已经成为:
- 的第一件事情,我注意到的是,如果我与调试器步将正确可靠失败。虽然这对我没有帮助。
- 我试过检查更新操作的RecordCount,但是当它假装成功时,它确实设置为1!
- 我试着做一个后续的SELECT语句来查看UPDATE是否真的发生了。尽管如此,即使我在UPDATE中放入了一个随机数,访问也会返回正确的结果。
- 我已经通过Access对象(如CurrentDb和TableDefs)寻找任何可靠的指示,表明它正在“脱机模式”或“缓存模式”下工作。我找不到任何指标。这对我很有帮助。
- 无论连接还是断开,链接表的RecordCount始终为-1。
- 我有断开并重新连接关联的TableDef通过修改和修复“连接”连接字符串。访问声称它重新连接好。
我不明白我看到的行为。 MSAccess是否在连接数据的某个缓存下运行?如果是这样,为什么它只能工作有时?如果他们真的有一些复杂的离线缓存模式,为什么没有记录在任何地方?不幸的是,我不允许在工作时喝酒。
到目前为止我所得出的最好结果是检查我是否有网络访问底层数据库文件。
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获取链接表的位置
我从来没有完全像你描述一个问题,但我做两分不同的事情:
我始终声明
Dim cdb As DAO.Database
,Set cdb = CurrentDB
,然后做cdb.Whatever
。有时候做CurrentDB.Whatever
的行为会有所不同。我总是做
cdb.Execute "SQL statement", dbFailOnError
。我认为这可能与你的问题特别相关。
感谢您的想法。我已经在做这两件事,但为了简单起见,我被骗了。 – 2013-04-10 18:11:12
也许,如你所说,数据库引擎执行UPDATE
针对存在于您的[Thing]
表中的缓存版本,以便稍后将其写入磁盘。但是,如果发生这种情况,Access似乎会在尝试执行磁盘写入时稍后发出错误。
老实说,我不明白你为什么没有得到一个错误。我认为在交易中尝试UPDATE
和use 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
这是一个好主意。我没有意识到这个冲动的想法。我会尽力而为。目前,我的黑客检查网络访问目前已到位,并且很难重新创建。 – 2013-04-18 18:44:31
我意识到这个线程是有点老,但现在我抓到在同样的情况描述,并希望增加我的两个便士。
我添加了上面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时会丢失任何数据。
+1为您的最后一句话。 (但是,问题的其余部分也值得+1。) – 2013-04-10 17:24:34
您是否使用'dbFailOnError'参数? – Scotch 2013-04-10 19:41:27
是的。对不起,我不清楚,我简化了这个例子,因为完整的代码有点麻烦。 – 2013-04-11 20:15:51