Reputation: 7269
I'm trying to retrieve the return value of a stored procedure in SQL Server 2005 as follows:
OleDbCommand comm = new OleDbCommand(process_name, connection);
comm.CommandType = CommandType.StoredProcedure;
for (int i = 0; i < process_parameters.Length; i++)
comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);
//Add output param
comm.Parameters.Add("@TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
comm.ExecuteNonQuery();
When ExecuteNonQuery() is called, however, I get back a OleDbException saying: "Procedure or function myStoredProcedure has too many arguments specified." My stored procedure begins as follows:
ALTER PROCEDURE [dbo].[spTabtempTestsINSERT]
(
@Param1 char (64),
@Param2 char (128),
@Param3 char (64),
)
AS
BEGIN
Declare @TestID int
And ends with the following:
RETURN @TestID
END
Does the fact that the return value is declared, rather than being passed as a parameter, have anything to do with it? If so, how can I get the return value of a param that's declared after the stored procedure begins? Thanks for your help.
UPDATE: I've tried the changes suggested so far, I added the following line:
OleDbCommand comm = new OleDbCommand(process_name, connection);
comm.CommandType = CommandType.StoredProcedure;
for (int i = 0; i < process_parameters.Length; i++)
comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);
var testID = (int)comm.ExecuteScalar();
Now when ExecuteScalar()
gets executed, I get a NullReferenceException with Object reference not set to an instance of an object.
Note: I also tried setting it to an integer int testID = (int)comm.ExecuteScalar();
and I still get the same error.
Upvotes: 1
Views: 8482
Reputation: 5176
I had the same issue, the problem is that you have to declare the return parameter first (before the input and output ones), this way it works:
OleDbCommand comm = new OleDbCommand(process_name, connection);
comm.CommandType = CommandType.StoredProcedure;
//Add the return param first
comm.Parameters.Add("@TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
for (int i = 0; i < process_parameters.Length; i++)
comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);
comm.ExecuteNonQuery();
Object return_value = comm.Parameters["@TestID"].Value;
Upvotes: 0
Reputation: 332
In response to the accepted answer...
Because you are setting the parameter's Direction
to ReturnValue
here:
comm.Parameters.Add("@ReturnValue", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
You don't need an OUTPUT
parameter in your stored procedure at all. You could change it back to:
ALTER PROCEDURE [dbo].[spTabtempTestsINSERT]
(
@Param1 char (64),
@Param2 char (128),
@Param3 char (64),
)
AS
BEGIN
Declare @TestID int
With:
RETURN @TestID
END
at the end and it would still work exactly as it does now.
It is purely coincidental that your ReturnValue
Parameter
in C# bears the same name as your OUTPUT
parameter. There is a separate parameter Direction
for OUTPUT
parameters.
Upvotes: 0
Reputation: 7269
Ok, I was able to get it to work properly. My problem was that, I neglected to declare any of the parameters as OUTPUT, I added an extra variable and set that as the output variable and had the stored procedure return that. After word I just checked that output parameter ,after calling the stored procedure, from my C# code, the following shows the changes:
ALTER PROCEDURE [dbo].[spTabtempTestsINSERT]
(
@Param1 char (64),
@Param2 char (128),
@Param3 char (64),
@ReturnValue int OUTPUT
)
AS
BEGIN
Declare @TestID int
And at the end make a simple change:
SET @ReturnValue = @TestID
RETURN @ReturnValue
END
Finally, back in my code:
OleDbCommand comm = new OleDbCommand(process_name, connection);
comm.CommandType = CommandType.StoredProcedure;
for (int i = 0; i < process_parameters.Length; i++)
comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);
//Add output param
comm.Parameters.Add("@ReturnValue", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
comm.ExecuteNonQuery();
Console.WriteLine("Stored Procedure returned a value of "+ comm.Parameters["@ReturnValue"].Value); //Success
Thank you all for your suggestions. Any alternatives or further insights are welcome.
Upvotes: 0
Reputation: 5358
remove these:
//Add output param
comm.Parameters.Add("@TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
comm.ExecuteNonQuery();
and use this instead: var testID = (int) comm.ExecuteScalar();
Upvotes: 0
Reputation: 2542
I thought ExecuteNonQuery() doesn't return anything from SQL..... am I missing something here?
Upvotes: 0
Reputation: 81660
Change
comm.ExecuteNonQuery();
to
int returnValue = (int) comm.ExecuteScalar();
And remove:
comm.Parameters.Add("@TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
Upvotes: 5