2011-10-05 57 views
7

Tengo la siguiente UDF en excel que usa ADO para conectarme a mi servidor MSSQL. Allí debería ejecutar el escalar udf "D100601RVDATABearingAllow".ADODB open recordset failed/"La operación no está permitida cuando el objeto está cerrado"

Por alguna razón, los parámetros que intento agregar no se envían al servidor sql. Solo en el servidor:

SELECT dbo.D100601RVDATABearingAllow 

llega.

MI 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 

Cuando uso adCmdStoredProc todo esto falla y en el depurador de VBA las propiedades del conjunto de registros tiene una gran cantidad de "operación no está permitida cuando el objeto está cerrado "(puede sonar un poco diferente, el mensaje es traducido)

Cuando no uso adCmdStoredProc me sale el mensaje de que la variable de Sujetador era no proporcionado.

Creo que tal vez algo esté mal en la forma en que abro el conjunto de registros. En otras pistas que leí acerca del uso de la opción "ESTABLECER NOCOUNT ENCENDIDO", pero tampoco funcionó.

¿Alguien tiene una idea? Saludos Lumpi

Respuesta

1

Usted no necesita SELECT la función del lado del servidor, simplemente proporcionar su nombre ("[tra-CAE400-1] .dbo.D100601RVDATABearingAllow") en la propiedad .CommandText. También debe establecer la propiedad .CommandType en "procedimiento almacenado" (property reference on w3schools.com).

Entonces adodb sabrá que está hablando de llamar a una función, y no tratar de enviar un simple comando sql.

Lo más probable es que le permita definir los parámetros en el objeto de comando. Pero los parámetros que defina en el objeto de comando se deben corresponder exactamente (en nombre y tipo) con los que se definen como los argumentos de la función en el servidor sql.

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

ADO Reference on microsoft.com

+0

Quité la instrucción SELECT. ¿Es correcto definir Param2 como adDouble cuando en el servidor el tipo es Float? la misma pregunta para adChar = varchar (20)? – Lumpi

+0

Para todos los interesados: Publiqué la misma pregunta en: http://www.codeproject.com/Questions/265573/ADODB-open-recordset-fails-Operation-is-not-allowe y obtuve algunos consejos interesantes, pero , el problema aún no está resuelto ... – Lumpi

13

encontré con este error también (en mi caso estoy usando un procedimiento almacenado para recuperar algo de información). Hice algunos cambios que causaron un mal funcionamiento de la ejecución.

El error desapareció cuando puse SET NOCOUNT ON como la primera instrucción del Procedimiento almacenado.

+0

¡Gracias! ¡Me ayudó de inmediato! – SalientBrain

0

También encontré esto con un procedimiento almacenado. ¿HIZO SET NOCOUNT = OFF? en la parte inferior de tu código? Eso es lo que funcionó para mí después de mucho googlear. Además, si tiene otro código que se ejecuta, debe ajustarlo en Nocount = on/off, INCLUIDAS las instrucciones de inserción y actualización. Pensarías que una declaración insertada no importaría, pero ajustar el código de esa manera es lo que me impidió cometer suicidio hoy.

1

Otra posible causa de esto son las instrucciones de depuración. Pasé demasiado tiempo tratando de entender por qué esto no me funcionaba, el Proc en la base de datos funcionó bien, se insertaron los datos que debía insertar, el código VBA funcionó bien, pero no había nada en el conjunto de registros . La solución final era ir a través de los procesos que se habían creado y eliminar las instrucciones de impresión. Para comprobar si este es el problema, ejecute su proceso en SQL Server manualmente, luego mire la pestaña de mensajes de los resultados, si hay algo allí que no sea "Comando completado con éxito". necesitas eliminar esos mensajes "SET NOCOUNT ON" eliminará los mensajes de recuento de filas, pero puede haber otros.

Supongo que después de 5 años el OP ha resuelto este problema en particular, por lo que esto es solo para alguien como yo que encuentra esto mientras busca el mismo problema.

0

En nuestra tienda a menudo utilizamos líneas de este tipo en nuestros procedimientos almacenados para ayudar con la depuración:

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

Esto también rompe la apertura de un conjunto de registros en VBA Excel. Creo que la respuesta completa a esta pregunta es, en el procedimiento almacenado:

  1. uso SET ROWCOUNT OFF
  2. extraer todas las instrucciones PRINT
  3. eliminar todas las declaraciones raiseError utilizados para la depuración (es decir, la gravedad de 0)
Cuestiones relacionadas