【问题标题】:MS Access VBA: Using workspace.OpenDatabase to connect to an unavailable SQL server via an ODBC connection - elegant recovery?MS Access VBA:使用 workspace.OpenDatabase 通过 ODBC 连接连接到不可用的 SQL 服务器 - 优雅恢复?
【发布时间】:2014-10-07 05:35:03
【问题描述】:

在使用 MS Access 表单作为某些 SQL 数据库前端的应用程序中,我使用 DBEngine.CreateWorkspace 获取工作区,然后使用 workspace.OpenDatabase 通过定义的 ODBC 系统 DSN 连接到我的远程 SQL 服务器。这一切都很好,直到有人断开远程 SQL 机器与网络的连接,或者关闭它,或者其他类似荒谬的事情。 (注意:我知道这个设置有很多可笑之处,但不幸的是,在这一点上这是不可避免的)

我的问题是: 有没有办法优雅地处理 VBA 代码中出现的超时和随后出现的“SQL Server 不存在或访问被拒绝”错误消息? workspace.OpenDatabase 会抛出一个我可以捕捉和处理的错误,但不会在两个弹出窗口出现并停止我的 VBA 代码之前,直到操作员单击 OK。

DoCmd.SetWarnings False 不会影响它,因为错误弹出窗口实际上并非来自 Access 本身 - 我认为它们来自底层 ODBC 进程或驱动它的 Jet Engine。

有什么想法吗?

【问题讨论】:

  • 在您尝试连接之前,您是否重新启动了 SQL Server 并且它当前是否正在运行?
  • 不,我知道它没有运行 - 这就是我试图在代码中捕获的内容。这不是“确保 SQL 服务器正在运行”的问题,而是“如果 SQL 服务器没有运行,我该如何优雅地从中恢复?”
  • 错误应该来自连接字符串,因为服务器没有运行。我想你把它放在 try and catch 块上。
  • 我在那里有 vba 错误处理,我可以捕获由 workspace.OpenDatabase 引发的错误 - 我的问题是在捕获该错误之前,会弹出两个弹出窗口并要求在代码之前单击可以继续。我想抑制这些特定的弹出窗口,以便我的错误处理可以继续工作。

标签: sql vba ms-access odbc jet


【解决方案1】:

可以在这里找到一个好的解决方案:

ACC2000:如何捕获 ODBC 登录错误消息 http://support.microsoft.com/kb/210319

以上内容来自 Access 2000,已有 14 年历史,但今天仍然可以正常工作。另一个可能的优势是您不必在应用程序中采用和引入 ADO。对于已经使用或拥有 ADO 的应用程序,没什么大不了的,但如果您的应用程序坚持使用一种数据对象模型,那么您不必潜在地引入 ADO。

上述的另一大好处是这可以有效地将您登录到数据库中,因此您可以避免在链接表中使用用户名和密码。这意味着您可以拥有不同的用户和登录名,而不必在链接表中重新链接或嵌入用户名或密码。

这里概述了上述连接技巧的这个奇妙技巧和结果:

电源提示:提高数据库连接的安全性

http://blogs.office.com/b/microsoft-access/archive/2011/04/08/power-tip-improve-the-security-of-database-connections.aspx

【讨论】:

  • 谢谢,这正是我想要的。我同意,能够使用相同的数据对象模型而不是引入第二个模型要整洁得多。感谢您的回答!
【解决方案2】:

我最终通过搜索“禁止 ODBC 连接失败警告”找到了可行的方法。

http://bytes.com/topic/access/answers/201502-how-suppress-odbc-connection-dialog 的 Trevor Best 提供

一些使用 ADO 建立数据库连接的代码允许 VBA 错误捕获在系统向您抛出任何弹出窗口之前捕获错误。

Function CanOpenSQLDbLB(pstrServer As String, pstrDb As String, pstrUser
As String, pstrPassword As String, Optional pfReportError As Boolean =
True) As Boolean

On Error GoTo CanOpenSQLDbLB_Err

Dim objConn As Object
Dim strConn As String
Dim strError As String, lngErr As Long
Const cstrSQLErr = "[Microsoft][ODBC SQL Server Driver][SQL Server]"

Set objConn = CreateObject("ADODB.Connection")

strConn = strConn & "DRIVER=SQL Server"
strConn = strConn & ";SERVER=" & pstrServer
strConn = strConn & ";APP=" & Application.Name
strConn = strConn & ";WSID=AWorkstation"
strConn = strConn & ";DATABASE=" & pstrDb

objConn.Open strConn, pstrUser, pstrPassword

CanOpenSQLDbLB = True

CanOpenSQLDbLB_Exit:
On Error Resume Next
objConn.Close
Set objConn = Nothing
Exit Function
CanOpenSQLDbLB_Err:
lngErr = Err.Number
strError = Err.Description

If InStr(1, strError, cstrSQLErr) Then
strError = "Error reported by server" & vbCr & vbCr &
Replace(strError, cstrSQLErr, "")
End If

Select Case lngErr
Case Else
If pfReportError Then
MsgBox strError, 16, "Error #" & Err & " Attempting to
open server database"
End If
End Select
Resume CanOpenSQLDbLB_Exit

End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 2015-08-19
    • 2013-03-17
    相关资源
    最近更新 更多