ADODB打开记录集失败/“对象关闭时不允许操作”

时间:2011-10-05 15:16:42

标签: sql-server vba ado adodb recordset

我在excel中有以下UDF,它使用ADO连接到我的MSSQL服务器。它应该执行标量udf“D100601RVDATABearingAllow”。

由于某种原因,我尝试追加的参数不会发送到sql server。仅在服务器上:

SELECT dbo.D100601RVDATABearingAllow

到达。

MY EXCEL UDF:

   Function RVDATA(Fastener) As Long

    Dim cnt As ADODB.Connection
    Dim rst As ADODB.Recordset
    Dim Cmd1 As ADODB.Command
    Dim stSQL As String

Const stADO As String = "Provider=SQLOLEDB.1;Data ................"
'----------------------------------------------------------
Set cnt = New ADODB.Connection
 With cnt
    .ConnectionTimeout = 3
    .CursorLocation = adUseClient
    .Open stADO
    .CommandTimeout = 3
 End With
'----------------------------------------------------------
Set Cmd1 = New ADODB.Command
    Cmd1.ActiveConnection = cnt
    Cmd1.CommandText = "dbo.D100601RVDATABearingAllow"
    Cmd1.CommandType = adCmdStoredProc
'----------------------------------------------------------
Set Param1 = Cmd1.CreateParameter("Fastener", adInteger, adParamInput, 5)
Param1.Value = Fastener
Cmd1.Parameters.Append Param1
Set Param1 = Nothing
'----------------------------------------------------------
Set rst = Cmd1.Execute()
RVDATA = rst.Fields(0).Value    
'----------------------------------------------------------
    rst.Close
    cnt.Close
    Set rst = Nothing
    Set cnt = Nothing
'----------------------------------------------------------
End Function

当我使用adCmdStoredProc时,整个事情都失败了,在vba调试器中,记录集的属性有很多“ 当对象关闭时不允许操作 ”(可能听起来有点不同,信息被翻译了)

当我不使用adCmdStoredProc时,我收到 变量 紧固件 未提供 的消息。

我认为打开记录集的方式可能有问题。 在其他方面,我读到了使用“SET NOCOUNT ON”选项,但这也不起作用。

有没有人有想法? 关心Lumpi

5 个答案:

答案 0 :(得分:16)

也遇到这个错误(在我的情况下,我使用存储过程来检索一些信息)。我做了一些改变导致执行失灵。

当我将SET NOCOUNT作为存储过程的第一个语句时,错误消失了。

答案 1 :(得分:1)

您不需要SELECT服务器端功能,只需在.CommandText属性中提供其名称(“[tra-CAE400-1] .dbo.D100601RVDATABearingAllow”)。 您还应将.CommandType属性设置为“stored-procedure”(property reference on w3schools.com)。

然后adodb会知道你在谈论调用一个函数,而不是试图发送一个普通的sql命令。

有可能它允许您在命令对象上定义参数。 但是,您在命令对象上定义的参数应该与(在名称和类型中)与在sql server中定义为函数参数的参数完全对应。

An example from microsoft.com on using the command-object with a stored procedure

ADO Reference on microsoft.com

答案 2 :(得分:1)

另一个可能的原因是调试语句。我花了太长时间试图弄清楚为什么这对我不起作用,数据库上的Proc工作得很好,它应该插入的数据插入,VBA代码工作正常,但记录集中没有任何内容。 最终解决方案是通过已构建的过程并删除PRINT语句。 要测试这是否是问题,请手动在SQL Server上运行proc,然后查看结果的“消息”选项卡,如果除“命令已成功完成”之外还有其他任何内容。你需要消除这些消息。 “SET NOCOUNT ON”将删除行计数消息,但可能还有其他消息。

我假设5年后OP解决了这个特殊问题,所以这对于像我这样的人来说,在寻找同样的问题时会发现这个问题。

答案 3 :(得分:0)

我还使用存储过程遇到了这个问题。你有没有设置NOCOUNT = OFF;在代码的底部?经过大量的谷歌搜索后,这对我有用。此外,如果您有任何其他运行的代码,则必须将其包装在Nocount = on / off,INCLUDING insert和update语句中。您会认为插入语句无关紧要,但以这种方式包装代码是我今天不能自杀的原因。

答案 4 :(得分:0)

在我们的商店中,我们经常在存储过程中使用这样的行来协助调试:

RAISERROR('Debug message here',0,1) WITH NOWAIT;

这也打破了在Excel vba中打开记录集的过程。我相信这个问题的完整答案是,在存储过程中:

  1. 使用SET ROWCOUNT OFF
  2. 删除所有PRINT语句
  3. 删除用于调试的所有RAISEERROR语句(即严重性为0)