2011-10-05 112 views
7

我在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

回答

1

你不需要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

ADO Reference on microsoft.com

+0

我删除了SELECT语句。在服务器上的类型为Float时,将Param2定义为adDouble是否正确? adChar = varchar(20)的同样问题? – Lumpi

+0

对于每个感兴趣的人:我发布了相同的问题:http://www.codeproject.com/Questions/265573/ADODB-open-recordset-fails-Operation-is-not-allowe,并得到了一些有趣的提示,但,问题仍然没有解决.. – Lumpi

13

就遇到了这个错误,以及(在我的情况下,我使用存储过程来获取的一些信息)。我做了一些改动,导致执行失灵。

当我将SET NOCOUNT设置为存储过程的第一条语句时,错误消失。

+0

谢谢!马上帮助我! – SalientBrain

0

我也遇到过这个存储过程。你设置了NOCOUNT = OFF;在你的代码的底部?这是什么为我工作后,大量的谷歌搜索。另外,如果您有任何其他代码运行,则必须将其包含在Nocount = on/off中,包括insert和update语句。你会认为插入声明并不重要,但是用这种方式包装代码使得我今天不会自杀。

1

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

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

0

在我们的商店,我们经常使用在我们的存储过程像这样的线路,以协助调试:

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

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

  1. 使用SET ROWCOUNT OFF
  2. 删除所有打印报表
  3. 删除用于调试(即0严重性)所有RAISEERROR陈述
相关问题