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

ADODB open recordset fails / "Operation is not allowed when object is closed"

提问人:Lumpi 提问时间:10/5/2011 最后编辑:Lumpi 更新时间:1/5/2017 访问量:15045

问:

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

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

SELECT dbo.D100601RVDATABearingAllow

到达。

我的 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 时,我收到未提供变量 Fastener 的消息。

我认为我打开记录集的方式可能有问题。 在其他踏板中,我读到有关使用“SET NOCOUNT ON”选项的信息,但这也没有用。

有人有想法吗? 问候 Lumpi

sql-server vba adodb 记录集

评论


答:

1赞 Roman 10/6/2011 #1

您不需要服务器端功能,只需提供其名称(“[tra-CAE400-1].dbo.D100601RVDATABearingAllow)。 此外,还应将该属性设置为“stored-procedure”(w3schools.com 上的属性引用)。SELECT.CommandText.CommandType

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

然后,它很可能允许您在命令对象上定义参数。 但是,在命令对象上定义的参数应(在名称和类型上)与定义为 SQL Server 中函数参数的参数完全对应。

microsoft.com 中关于将命令对象与存储过程一起使用的示例

ADO 关于 microsoft.com 的参考

评论

0赞 Lumpi 10/6/2011
我删除了 SELECT 语句。当服务器上的类型为 Float 时,将 Param2 定义为 adDouble 是否正确?adChar = varchar(20) 的相同问题?
0赞 Lumpi 10/16/2011
对于所有感兴趣的人:我在以下位置发布了相同的问题:codeproject.com/Questions/265573/......并且确实得到了一些有趣的提示,但是,问题仍然没有解决。
18赞 DigCamara 3/9/2013 #2

也遇到了这个错误(就我而言,我正在使用存储过程来检索一些信息)。我做了一些更改,导致执行失败。

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

0赞 Drew Thompson 9/3/2014 #3

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

1赞 9Squirrels 10/19/2016 #4

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

我假设 5 年后 OP 已经解决了这个特定问题,所以这只适用于像我这样在寻找相同问题时发现这个问题的人。

0赞 Tom Regan 1/5/2017 #5

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

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

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

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