2011-10-05 35 views
7

Ho la seguente UDF in excel che utilizza ADO per connettersi al mio server MSSQL. Lì dovrebbe eseguire lo scalf udf "D100601RVDATABearingAllow".ADODB recordset aperto non riesce/"Operazione non consentita quando l'oggetto è chiuso"

Per qualche motivo i parametri che provo ad aggiungere non vengono inviati al server sql. Solo al server:

SELECT dbo.D100601RVDATABearingAllow 

arriva.

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 

Quando uso adCmdStoredProc il tutto non riesce e nel debugger vba le proprietà del set di record ha un sacco di "operazione non è consentita quando l'oggetto è chiuso "(può sembrare un po 'diverso, il messaggio viene tradotto)

Quando non uso adCmdStoredProc ottengo il messaggio che il variabile Fastener era non fornito.

Penso che forse qualcosa non va nel modo in cui apro il recordset. In altre pedate ho letto sull'utilizzo dell'opzione "SET NOCOUNT ON", ma non ha funzionato.

Qualcuno ha un'idea? Saluti Lumpi

risposta

1

Non c'è bisogno di SELECT la funzione lato server, basta fornire il proprio nome ("[tra-CAE400-1] .dbo.D100601RVDATABearingAllow") nella proprietà .CommandText. Inoltre, è necessario impostare la proprietà .CommandType su "stored-procedure" (property reference on w3schools.com).

Quindi adodb saprà che si sta parlando di chiamare una funzione e non si sta tentando di inviare un comando sql semplice.

È probabile che consenta di definire i parametri sull'oggetto comando. Ma i parametri definiti sull'oggetto comando devono corrispondere esattamente (nel nome e nel tipo) a quelli definiti come argomenti della funzione nel server sql.

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

ADO Reference on microsoft.com

+0

Ho rimosso l'istruzione SELECT. È corretto definire Param2 come adDouble quando sul server il tipo è Float? stessa domanda per adChar = varchar (20)? – Lumpi

+0

Per tutti quelli che sono interessati: ho postato la stessa domanda su: http://www.codeproject.com/Questions/265573/ADODB-open-recordset-fails-Operation-is-not-allowe e ho ricevuto alcuni suggerimenti interessanti ma , il problema non è ancora risolto .. – Lumpi

13

imbattuto in questo errore e (nel mio caso io sto usando una stored procedure per recuperare alcune informazioni). Ho apportato alcune modifiche che hanno causato il malfunzionamento dell'esecuzione.

L'errore è scomparso quando ho inserito SET NOCOUNT come prima istruzione della stored procedure.

+0

Grazie! Mi ha aiutato subito! – SalientBrain

0

Mi sono anche imbattuto in questo con una stored procedure. Hai impostato NOCOUNT = OFF; nella parte inferiore del tuo codice? Questo è ciò che ha funzionato per me dopo un sacco di googling. Inoltre, se hai un altro codice che viene eseguito, devi avvolgerlo in Nocount = on/off, INCLUDERE le istruzioni di inserimento e aggiornamento. Si potrebbe pensare che una dichiarazione di inserimento non abbia importanza, ma avvolgere il codice in questo modo è ciò che mi ha impedito di suicidarmi oggi.

1

Un'altra possibile causa di ciò sono le dichiarazioni di debug. Ho appena passato troppo tempo a cercare di capire perché questo non avrebbe funzionato per me, il Proc sul database funzionava bene, i dati che doveva inserire erano inseriti, il codice VBA funzionava bene, ma non c'era nulla nel recordset . La soluzione finale era di esaminare i proc creati e rimuovere le istruzioni PRINT. Per verificare se questo è il problema, eseguire manualmente il proc su SQL Server, quindi controllare la scheda dei messaggi dei risultati, se c'è qualcosa di diverso da "Comando (i) completato correttamente". è necessario eliminare quei messaggi. "SET NOCOUNT ON" eliminerà i messaggi di conteggio delle righe, ma potrebbero essercene altri.

Suppongo che dopo 5 anni l'OP abbia risolto questo particolare problema, quindi questo è solo per chiunque come me che trova questo mentre cerca lo stesso problema.

0

Nel nostro negozio si usano spesso linee come questo nella nostra stored procedure per assistere con il debug:

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

Questo rompe anche l'apertura di un set di record in Excel VBA. Credo che la risposta completa per questa domanda è, nella stored procedure:

  1. uso SET ROWCOUNT OFF
  2. rimuovere tutte le istruzioni PRINT
  3. rimuovere tutte le dichiarazioni RaiseError utilizzati per il debug (vale a dire la gravità di 0)
Problemi correlati