【问题标题】:Executing stored procedure in MS Access through ADO connection - removing application role通过 ADO 连接在 MS Access 中执行存储过程 - 删除应用程序角色
【发布时间】:2020-02-17 10:27:26
【问题描述】:

我有一个在 MS Access 中开发的应用程序,它使用 ADO 连接到 SQL Server (Microsoft SQL Server 2017) 来执行大量存储过程。 ADO 连接都是通过应用程序角色完成的,以限制权限。

在最新的更新中,我创建了一些新的存储过程,它们返回多个记录集,并粘贴在 Excel 中。我的问题是,当我执行这些存储过程时,应用程序角色被删除......查询运行没有任何问题,但是当它完成运行时,应用程序角色未设置。

以下是在 VBA Access 中调用的存储过程之一的示例:


Public Function CDTExceptionsReport() As ADODB.Recordset

    On Error GoTo ErrorHandler

    Set objConn = DB.MaintainConnection

    On Error GoTo 0

    If objCmd_ER Is Nothing Then
        Set objCmd_ER = New ADODB.Command
        With objCmd_ER
            .CommandType = adCmdText
            .CommandTimeout = 60 ' increase command 
            .CommandText = "EXEC tool.ExceptionsReport;"
            .Prepared = True
            ' set connection object
            .ActiveConnection = objConn

        End With
    End If

    Set CDTExceptionsReport = objCmd_ER.Execute

    On Error GoTo 0
     Exit Function
ErrorHandler:
    MsgBox "Error: " & Err.DESCRIPTION & vbNewLine & "Number: " & Err.Number
    On Error GoTo 0 ' reset error handling
End Function

注意objConn 是我的连接对象,objCmd_ER 是我的全局命令对象。

通过 VBA 中的即时终端,我可以在调试模式下使用以下命令检查正在激活的角色:

Set RS = objConn.Execute("SELECT CURRENT_USER")
?RS.Fields(0)

如果我在objCmd_ER.Execute 行之前运行它,我可以看到应用程序角色仍在使用中。但是,当我在该语句之后立即运行它时,应用程序角色被删除并返回我的 Windows 用户名。有谁之前经历过这个吗?

我已经直接在 SQL Server 中执行了这个存储过程,它工作正常并且不会注销应用程序角色。因此我的想法是它与 ADO 连接有关。

请让我知道提供哪些进一步的详细信息会有所帮助。存储过程不包含任何 DDL 或 DML 语言 - 只有 4 个选择查询。

谢谢

【问题讨论】:

  • 请注意,应用程序角色不能很好地与连接池配合使用。在关闭连接之前使用sp_unsetapprole,如here 所述。
  • 谢谢,@DanGuzman - 有很多存储过程会重复执行。您是否建议我必须在我调用的每个存储过程之前和之后(分别)设置和取消设置 approle?由于我在这里提到的,我倾向于不关闭连接,因为下一个存储过程永远不会超过 30 秒。
  • 不是在每次调用之前设置/取消设置,而是在每个连接打开后设置,并在连接关闭/关闭之前取消设置。否则,您需要禁用连接池。
  • 我确实在打开连接后设置了应用程序角色。我从不关闭连接;我认为他们最终会超时。会不会跟这有关系?
  • 如果您从不关闭连接或通过连接字符串关闭池,则使用应用程序角色的连接池将不是问题。我怀疑您遇到的问题是因为 ADO 正在背后打开连接,因为指定的连接已在使用中。在调试器中运行SELECT @@SPID;,看看session id是否不同。

标签: sql-server vba ms-access ado


【解决方案1】:

永远不要这样做!

.ActiveConnection = objConn

这会将连接对象objConn 转换为连接字符串,然后使用该连接字符串创建一个新连接,并将其用作活动连接。

相反,请始终这样做:

Set .ActiveConnection = objConn

这实际上将活动连接设置为您的连接对象。

【讨论】:

  • 谢谢,埃里克。不幸的是,这并没有使错误消失...
  • 嗨尼克。我正在尝试使用 ADO 并使用应用程序角色连接到 SQL Server。我可以使用简单的用户连接到服务器。我创建了一个应用程序角色,但它不起作用“用户'testApp'登录失败”。能说说如何配置应用角色和你使用的连接字符串吗?
猜你喜欢
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多