ADODB打开记录集失败/“对象关闭时不允许操作”
我在Excel中使用ADO连接到我的MSSQL服务器时有以下UDF。在那里它应该执行标量udf“D100601RVDATABearingAllow”。ADODB打开记录集失败/“对象关闭时不允许操作”
由于某些原因,我尝试附加的参数不会发送到sql服务器。仅在服务器上:
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
你不需要SELECT
服务器端功能,只需提供它的名字(“[反-CAE400-1] .dbo.D100601RVDATABearingAllow”)在.CommandText
财产。 此外,您应该将.CommandType
属性设置为“存储过程”(property reference on w3schools.com)。
然后adodb会知道你在说的是调用一个函数,而不是试图发送一个普通的sql-command。
然后它可以让你在命令对象上定义参数。 但是您在命令对象上定义的参数应该完全对应(在名称和类型中)与那些被定义为sql server中函数参数的参数。
An example from microsoft.com on using the command-object with a stored procedure
就遇到了这个错误,以及(在我的情况下,我使用存储过程来获取的一些信息)。我做了一些改动,导致执行失灵。
当我将SET NOCOUNT设置为存储过程的第一条语句时,错误消失。
谢谢!马上帮助我! – SalientBrain
我也遇到过这个存储过程。你设置了NOCOUNT = OFF;在你的代码的底部?这是什么为我工作后,大量的谷歌搜索。另外,如果您有任何其他代码运行,则必须将其包含在Nocount = on/off中,包括insert和update语句。你会认为插入声明并不重要,但是用这种方式包装代码使得我今天不会自杀。
另一个可能的原因是调试语句。我花了太长时间试图弄清楚为什么这对我不起作用,数据库上的Proc工作正常,它应该插入的数据被插入,VBA代码工作正常,但是记录集中没有任何内容。 最终的解决方案是通过已经构建的procs并删除PRINT语句。 要测试这是否是问题,请手动在SQL Server上运行proc,然后查看结果的消息选项卡,如果除“命令已成功完成”以外还有其他任何内容。你需要消除这些消息。 “SET NOCOUNT ON”将排除行计数消息,但可能还有其他消息。
我假设5年后OP已经解决了这个特殊问题,所以这只适用于像我这样的人,在寻找相同问题时发现这一点。
在我们的商店,我们经常使用在我们的存储过程像这样的线路,以协助调试:
RAISERROR('Debug message here',0,1) WITH NOWAIT;
这也打破了在Excel VBA中打开一个记录集。我相信这个问题的完整的答案是,在存储过程:
- 使用SET ROWCOUNT OFF
- 删除所有打印报表
- 删除用于调试(即0严重性)所有RAISEERROR陈述
我删除了SELECT语句。在服务器上的类型为Float时,将Param2定义为adDouble是否正确? adChar = varchar(20)的同样问题? – Lumpi
对于每个感兴趣的人:我发布了相同的问题:http://www.codeproject.com/Questions/265573/ADODB-open-recordset-fails-Operation-is-not-allowe,并得到了一些有趣的提示,但,问题仍然没有解决.. – Lumpi