2011-10-05 137 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陳述
相關問題