Dear Group,
I would like to read the input and output parameters of a stored
procedure within the Connection.ExecuteComplete event handler.
Unfortunately, I have found that if I do this while using
Command.Execute, the Command.Execute returns nothing rather than the
expected recordset! I have found that if I comment out the reading of
the parameters collection, the correct recordset is returned.
Furthermore, if I leave the parameter reading lines commented out and
instead look at the parameters in the immediate window or using the
locals window, command.execute will return Nothing. Any help would be
appreciated.
EXAMPLE OUTPUT
Without Printing Dealer
recordset value ado is confusing
With Printing Dealer
Dealer 500
recordset is nothing
EXAMPLE STORED PROCEDURE (put in any sql server database, does not use
any tables)
create PROCEDURE [dbo].[pr_test4]
@ListDate datetime,
@DealerID int,
@outputID int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
select @outputID = @DealerID + 1
select ('ado is confusing')
END
EXAMPLE CLASS MODULE that watches for events, must set server strings
to match:
Public WithEvents con As ADODB.Connection
Public PrintDealer As Boolean
Public Sub init()
Set con = New ADODB.Connection
con.Open "Provider=SQLOLEDB.1;Data Source=xxx;Initial
Catalog=xxx;Integrated Security=SSPI;"
con.CursorLocation = adUseClient
End Sub
Private Sub con_ExecuteComplete(ByVal RecordsAffected As Long, ByVal
pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal
pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, ByVal
pConnection As ADODB.Connection)
If PrintDealer Then
Debug.Print "Dealer " & pCommand.Parameters("@DealerID").Value
End If
End Sub
Public Sub Test(cmd As ADODB.Command)
Dim rs As ADODB.Recordset
Set rs = cmd.Execute
If rs Is Nothing Then
Debug.Print "recordset is nothing"
Else
rs.MoveFirst
Debug.Print "recordset value " & rs.Fields(0).Value
End If
End Sub
EXAMPLE CODE MODULE to call everything
Sub TestSub()
Dim o As New SimpleTest
o.init
Dim cmd As ADODB.Command
Debug.Print "Without Printing Dealer"
pr_test4 cmd, o.con, #4/1/2009#, 500
o.Test cmd
' o.doExecuteRS cmd
Debug.Print ""
Debug.Print "With Printing Dealer"
o.PrintDealer = True
pr_test4 cmd, o.con, #4/1/2009#, 500
o.Test cmd
End Sub
Public Function pr_test4(cmd As ADODB.Command, con As
ADODB.Connection, _
ByVal ListDate As Variant, ByVal DealerID) As Boolean
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = con
cmd.CommandText = "pr_test4"
cmd.CommandType = adCmdStoredProc
cmd.Parameters.Append cmd.CreateParameter("@ListDate",
adDBTimeStamp, adParamInput, 0, ListDate)
cmd.Parameters.Append cmd.CreateParameter("@DealerID", adInteger,
adParamInput, 0, DealerID)
cmd.Parameters.Append cmd.CreateParameter("@OutputID", adInteger,
adParamOutput)
pr_test4 = True
End Function
William Vaughn - 26 Jul 2007 04:00 GMT
The problem is that the TDS packet with the OUTPUT parameters (and the
RETURN int) is sent last--after the rowset.
If you ask too early, it can confuse ADO (and ADO.NET).

Signature
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant, Dad, Grandpa
Microsoft MVP
INETA Speaker
www.betav.com
www.betav.com/blog/billva
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
Visit www.hitchhikerguides.net to get more information on my latest book:
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
and Hitchhiker's Guide to SQL Server 2005 Compact Edition (EBook)
-----------------------------------------------------------------------------------------------------------------------
> Dear Group,
>
[quoted text clipped - 98 lines]
> pr_test4 = True
> End Function
Alok - 26 Jul 2007 14:05 GMT
> The problem is that the TDS packet with the OUTPUT parameters (and the
> RETURN int) is sent last--after the rowset.
> If you ask too early, it can confuse ADO (and ADO.NET).
True, but what you say seems like it should only apply to output
parameters. In my code example, DealerID is an input paramter. I
should also emphasize that there is no problem looking at anything in
the ExecuteComplete (note that i use a client side cursor) the only
problem is that Command.Execute returns Nothing instead of the
recordset. I should also note that I can look at the same input
parameter in WillExecute without affecting the return value of
Command.Execute.
William Vaughn - 26 Jul 2007 18:34 GMT
I discussed this (years ago) in my book ADO and ADO.NET Examples and Best
Practices. ADO classic will not let you touch any of the parameters marked
as output direction. Yes, you can see the input parameters but until the
rowset is fully fetched, ADO classic gets confused and does not behave well
at all if you reference an output Parameter. I expect that "ExecuteComplete"
means that the query has been executed, not that the rowset has been
fetched. It's been awhile since I looked at this but if it follows the
ADO.NET pattern, that's the case...
hth

Signature
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant, Dad, Grandpa
Microsoft MVP
INETA Speaker
www.betav.com
www.betav.com/blog/billva
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
Visit www.hitchhikerguides.net to get more information on my latest book:
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
and Hitchhiker's Guide to SQL Server 2005 Compact Edition (EBook)
-----------------------------------------------------------------------------------------------------------------------
>> The problem is that the TDS packet with the OUTPUT parameters (and the
>> RETURN int) is sent last--after the rowset.
[quoted text clipped - 8 lines]
> parameter in WillExecute without affecting the return value of
> Command.Execute.