Keyman
asked on
Problem with ADO Output Parameter returning value from SQL Sproc
Here is my VBA code
mcmd.ActiveConnection = mcnn
mcmd.CommandType = adCmdStoredProc
mcmd.CommandText = "pGetChangeOrderNumbers"
mcmd.Parameters.Append mcmd.CreateParameter("@Baa
mcmd.Parameters.Append mcmd.CreateParameter("RowC
Set mrs = mcmd.Execute()
MsgBox mcmd.Parameters(1)
MsgBox mcmd.Parameters("RowCnt")
Here is my Sproc from MS SQL
CREATE PROC pGetChangeOrderNumbers
@SO int,
@RowCnt int = NULL output
AS
SELECT C.ChangeOrderNum
FROM tblChangeOrder C
WHERE (C.BaanSalesOrderNum = @SO)
SELECT @RowCnt = @@ROWCOUNT
The Msgbox is empty. I do not get the Rowcount value.
When I run the sproc in the QA using the same input value it returns the proper rowcount.
Can anyone help?
Sean, you need to raise this request in community support I think.
Hi Keyman
If you SET @RowCnt = @@ROWCOUNT
instead of
SELECT @RowCnt = @@ROWCOUNT
you would only be returning one recordset instead of two, and the outputparam would be available to you.
may also be able to get the outparam using the ADO NextRecordset method
Example from ADO help:
'BeginNextRecordsetVB
Public Sub NextRecordsetX()
Dim rstCompound As ADODB.Recordset
Dim strCnn As String
Dim intCount As Integer
' Open compound recordset.
strCnn = "Provider=sqloledb;" & _
"Data Source=MyServer;Initial Catalog=Pubs;User Id=sa;Password=; "
Set rstCompound = New ADODB.Recordset
rstCompound.Open "SELECT * FROM Authors; " & _
"SELECT * FROM stores; " & _
"SELECT * FROM jobs", strCnn, , , adCmdText
' Display results from each SELECT statement.
intCount = 1
Do While Not (rstCompound Is Nothing)
Debug.Print "Contents of recordset #" & intCount
Do While Not rstCompound.EOF
Debug.Print , rstCompound.fields(0), _
rstCompound.fields(1)
rstCompound.MoveNext
Loop
Set rstCompound = rstCompound.NextRecordset
intCount = intCount + 1
Loop
End Sub
'EndNextRecordsetVB
Alan
If you SET @RowCnt = @@ROWCOUNT
instead of
SELECT @RowCnt = @@ROWCOUNT
you would only be returning one recordset instead of two, and the outputparam would be available to you.
may also be able to get the outparam using the ADO NextRecordset method
Example from ADO help:
'BeginNextRecordsetVB
Public Sub NextRecordsetX()
Dim rstCompound As ADODB.Recordset
Dim strCnn As String
Dim intCount As Integer
' Open compound recordset.
strCnn = "Provider=sqloledb;" & _
"Data Source=MyServer;Initial Catalog=Pubs;User Id=sa;Password=; "
Set rstCompound = New ADODB.Recordset
rstCompound.Open "SELECT * FROM Authors; " & _
"SELECT * FROM stores; " & _
"SELECT * FROM jobs", strCnn, , , adCmdText
' Display results from each SELECT statement.
intCount = 1
Do While Not (rstCompound Is Nothing)
Debug.Print "Contents of recordset #" & intCount
Do While Not rstCompound.EOF
Debug.Print , rstCompound.fields(0), _
rstCompound.fields(1)
rstCompound.MoveNext
Loop
Set rstCompound = rstCompound.NextRecordset
intCount = intCount + 1
Loop
End Sub
'EndNextRecordsetVB
Alan
ASKER
The SELECT @RowCnt = @@ROWCOUNT does not return a second record set.
It sets the value of the variable.
Here try this in you QA
Declare @V as int
SELECT @V = 1 <- This will not return a record set
SELECT @V <- Add this to the query and it will return a single row rs with 1 as the value.
It sets the value of the variable.
Here try this in you QA
Declare @V as int
SELECT @V = 1 <- This will not return a record set
SELECT @V <- Add this to the query and it will return a single row rs with 1 as the value.
Hi sean,
hmm... certainly seems to be returning only one recordset, I apologise for being wrong.
However I know that you can get the output param while the recordset is still open.
I think you are actually getting it but you have no defined size for the output in your append item, therefor you are returning the first 0 bytes of the output param, hence the empty msgbox.
This works, tested...
Function testit() As Integer
Dim rs As ADODB.Recordset
Dim mSalesOrderNumber As Integer
Dim intRowCnt As Integer
mSalesOrderNumber = 1
Set rs = New ADODB.Recordset
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
With cmd
.CommandText = "pGetChangeOrderNumbers"
.CommandType = adCmdStoredProc
.Parameters.Append .CreateParameter("@BaanSal esOrderNum ", adInteger, adParamInput, 4, mSalesOrderNumber)
.Parameters.Append .CreateParameter("@RowCnt" , adInteger, adParamOutput, 4)
Set .ActiveConnection = CurrentProject.Connection
Set rs = .Execute
intRowCnt = .Parameters.Item("@RowCnt" )
With rs
MsgBox intRowCnt
.Close ' rs is still open
End With
Set rs = Nothing
End With
Set cmd = Nothing
testit = intRowCnt
End Function
Take care
Alan
Still more than happy to refund your points, no big deal
Just give me the word..
":0)
hmm... certainly seems to be returning only one recordset, I apologise for being wrong.
However I know that you can get the output param while the recordset is still open.
I think you are actually getting it but you have no defined size for the output in your append item, therefor you are returning the first 0 bytes of the output param, hence the empty msgbox.
This works, tested...
Function testit() As Integer
Dim rs As ADODB.Recordset
Dim mSalesOrderNumber As Integer
Dim intRowCnt As Integer
mSalesOrderNumber = 1
Set rs = New ADODB.Recordset
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
With cmd
.CommandText = "pGetChangeOrderNumbers"
.CommandType = adCmdStoredProc
.Parameters.Append .CreateParameter("@BaanSal
.Parameters.Append .CreateParameter("@RowCnt"
Set .ActiveConnection = CurrentProject.Connection
Set rs = .Execute
intRowCnt = .Parameters.Item("@RowCnt"
With rs
MsgBox intRowCnt
.Close ' rs is still open
End With
Set rs = Nothing
End With
Set cmd = Nothing
testit = intRowCnt
End Function
Take care
Alan
Still more than happy to refund your points, no big deal
Just give me the word..
":0)
it's a weird thing:
I can use the .nextrecordset method without error once but not twice, sorta indicating that there are two instantiated recordsets, even though query analyser doesnt show two results grids.
With rs
MsgBox intRowCnt
Set rs = rs.NextRecordset ' no error here
Debug.Print .Fields(0)
Set rs = rs.NextRecordset ' error here
Debug.Print .Fields(0)
Set rs = rs.NextRecordset
Debug.Print .Fields(0)
.Close
End With
go figure ...
Take care Sean
Alan
I can use the .nextrecordset method without error once but not twice, sorta indicating that there are two instantiated recordsets, even though query analyser doesnt show two results grids.
With rs
MsgBox intRowCnt
Set rs = rs.NextRecordset ' no error here
Debug.Print .Fields(0)
Set rs = rs.NextRecordset ' error here
Debug.Print .Fields(0)
Set rs = rs.NextRecordset
Debug.Print .Fields(0)
.Close
End With
go figure ...
Take care Sean
Alan
ASKER
I cannot get it to work before the recordset close.
Here is my new working code.
With mcmd
.ActiveConnection = mcnn
.CommandType = adCmdStoredProc
.CommandText = "pGetChangeOrderNumbers"
.Parameters.Append mcmd.CreateParameter("@Baa nSalesOrde rNum", adInteger, adParamInput, , mSalesOrderNumber)
.Parameters.Append mcmd.CreateParameter("RowC nt", adInteger, adParamOutput, 4)
Set mrs = mcmd.Execute()
'intRowCnt = .Parameters.Item("RowCnt")
'MsgBox intRowCnt
End With
If Not mrs.EOF Then
mChangeOrdersExist = True
mChangeOrderNumbers = mrs.GetString(adClipString , ColumnDelimeter:=";", RowDelimeter:=";")
Else
mChangeOrdersExist = False
End If
mrs.Close
'We must close the recordset before we can get the output parameter sent from the sproc
If mChangeOrdersExist = True Then
mNumberOfChangeOrders = mcmd.Parameters.Item("RowC nt")
Else
mNumberOfChangeOrders = 0
End If
mcnn.Close
If I unremark the lines that show the output paramater before the close of the recordset I get NULL
Here is my new working code.
With mcmd
.ActiveConnection = mcnn
.CommandType = adCmdStoredProc
.CommandText = "pGetChangeOrderNumbers"
.Parameters.Append mcmd.CreateParameter("@Baa
.Parameters.Append mcmd.CreateParameter("RowC
Set mrs = mcmd.Execute()
'intRowCnt = .Parameters.Item("RowCnt")
'MsgBox intRowCnt
End With
If Not mrs.EOF Then
mChangeOrdersExist = True
mChangeOrderNumbers = mrs.GetString(adClipString
Else
mChangeOrdersExist = False
End If
mrs.Close
'We must close the recordset before we can get the output parameter sent from the sproc
If mChangeOrdersExist = True Then
mNumberOfChangeOrders = mcmd.Parameters.Item("RowC
Else
mNumberOfChangeOrders = 0
End If
mcnn.Close
If I unremark the lines that show the output paramater before the close of the recordset I get NULL
Hi sean,
it's sometning to do with the connection object because if I set the command.activeconnection to currentproject.connection it works, but If I instantiate a separate connection based on the currentproject.baseconnect ionstring it returns zero.
' This works....
With mcmd
.ActiveConnection = CurrentProject.Connection
.CommandType = adCmdStoredProc
.CommandText = "pGetChangeOrderNumbers"
.Parameters.Append mcmd.CreateParameter("@Baa nSalesOrde rNum", adInteger, adParamInput, 4, mSalesOrderNumber)
.Parameters.Append mcmd.CreateParameter("RowC nt", adInteger, adParamOutput, 4)
Set mrs = mcmd.Execute
intRowCnt = .Parameters.Item("RowCnt")
MsgBox intRowCnt
End With
' this fails...
mcnn.Open CurrentProject.BaseConnect ionString
mSalesOrderNumber = 1
With mcmd
.ActiveConnection = mcnn
.CommandType = adCmdStoredProc
.CommandText = "pGetChangeOrderNumbers"
.Parameters.Append mcmd.CreateParameter("@Baa nSalesOrde rNum", adInteger, adParamInput, 4, mSalesOrderNumber)
.Parameters.Append mcmd.CreateParameter("RowC nt", adInteger, adParamOutput, 4)
Set mrs = mcmd.Execute
intRowCnt = .Parameters.Item("RowCnt")
MsgBox intRowCnt
End With
' this works...
mcnn.Open CurrentProject.Connection
mSalesOrderNumber = 1
With mcmd
.ActiveConnection = mcnn
.CommandType = adCmdStoredProc
.CommandText = "pGetChangeOrderNumbers"
.Parameters.Append mcmd.CreateParameter("@Baa nSalesOrde rNum", adInteger, adParamInput, 4, mSalesOrderNumber)
.Parameters.Append mcmd.CreateParameter("RowC nt", adInteger, adParamOutput, 4)
Set mrs = mcmd.Execute
intRowCnt = .Parameters.Item("RowCnt")
MsgBox intRowCnt
End With
maybe debug.? CurrentProject.connection and compare it with your mcnn connection string.
Alan
it's sometning to do with the connection object because if I set the command.activeconnection to currentproject.connection it works, but If I instantiate a separate connection based on the currentproject.baseconnect
' This works....
With mcmd
.ActiveConnection = CurrentProject.Connection
.CommandType = adCmdStoredProc
.CommandText = "pGetChangeOrderNumbers"
.Parameters.Append mcmd.CreateParameter("@Baa
.Parameters.Append mcmd.CreateParameter("RowC
Set mrs = mcmd.Execute
intRowCnt = .Parameters.Item("RowCnt")
MsgBox intRowCnt
End With
' this fails...
mcnn.Open CurrentProject.BaseConnect
mSalesOrderNumber = 1
With mcmd
.ActiveConnection = mcnn
.CommandType = adCmdStoredProc
.CommandText = "pGetChangeOrderNumbers"
.Parameters.Append mcmd.CreateParameter("@Baa
.Parameters.Append mcmd.CreateParameter("RowC
Set mrs = mcmd.Execute
intRowCnt = .Parameters.Item("RowCnt")
MsgBox intRowCnt
End With
' this works...
mcnn.Open CurrentProject.Connection
mSalesOrderNumber = 1
With mcmd
.ActiveConnection = mcnn
.CommandType = adCmdStoredProc
.CommandText = "pGetChangeOrderNumbers"
.Parameters.Append mcmd.CreateParameter("@Baa
.Parameters.Append mcmd.CreateParameter("RowC
Set mrs = mcmd.Execute
intRowCnt = .Parameters.Item("RowCnt")
MsgBox intRowCnt
End With
maybe debug.? CurrentProject.connection and compare it with your mcnn connection string.
Alan
Hi Sean,
gotta take a break for a little while here, I know you have it solved with closing the recordset, don't know about you but it irks me somwhat, when I know something should work, but it doesn't.
check the diff:
?CurrentProject.BaseConnec tionString
PROVIDER=SQLOLEDB.1;INTEGR ATED SECURITY=SSPI;PERSIST SECURITY INFO=FALSE;INITIAL CATALOG=MyData;DATA SOURCE=GONDOR
?CurrentProject.Connection
Provider=MSDataShape.1;Per sist Security Info=False;Data Source=GONDOR;Integrated Security=SSPI;Initial Catalog=MyData;Data Provider=SQLOLEDB.1
One has a dataprovider and a provider, while the other only has a provider, the one that works has both.
Alan
gotta take a break for a little while here, I know you have it solved with closing the recordset, don't know about you but it irks me somwhat, when I know something should work, but it doesn't.
check the diff:
?CurrentProject.BaseConnec
PROVIDER=SQLOLEDB.1;INTEGR
?CurrentProject.Connection
Provider=MSDataShape.1;Per
One has a dataprovider and a provider, while the other only has a provider, the one that works has both.
Alan
ASKER
Hmm.. well all my connections are to a remote MS SQL server.
I am not working on any linked tables through ODBC or tables withing the access MDB file itself.
I am not working on any linked tables through ODBC or tables withing the access MDB file itself.
Ohhh, for some reason I was under the impression that this was an ADP.
I'll check into it a bit later, not interested in points here Sean, it's a good question.
Will create an mdb frontend later and see what/if connection string works, probably the same as ASP/ADO connection
take care...
Alan
I'll check into it a bit later, not interested in points here Sean, it's a good question.
Will create an mdb frontend later and see what/if connection string works, probably the same as ASP/ADO connection
take care...
Alan
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
In deed that does work as well. I will award you the points...
Thanks Alan!
Sean
Thanks Alan!
Sean
thanks Sean,
success with your app!
Alan
success with your app!
Alan
ASKER
Here is the answer
SYMPTOMS
When using ADO and the default server side cursor is out, parameters return NULL values.
CAUSE
ADO doesn't fill in the out parameters for a recordset created using adUseServer (server side cursor) until the returned recordset is closed.
I close the recordset and I get the right values now.
Please do not answer this and return my points
Thanks
Sean