Using ExecuteReader I am able to return a DataReader
, but the out
parameter is returning 0.
Using ExecuteNonQuery I am able to retrieve the out
parameter (with the correct value) but the ExecuteNonQuery
does not return a DataReader
.
Here is the procedure to give context:
CREATE PROCEDURE [dbo].[SelectDays]
@dateStart datetime,
@dateEnd datetime,
@recordCount bigint out
AS
BEGIN
select @recordCount = count(*)
from dbo.[Days]
where [Date]>=@dateStart and [Date]<=@dateEnd;
select [ID],[Name]
from dbo.[Days]
where [Date]>=@dateStart and [Date]<=@dateEnd;
END
Is there a way I could return a DataReader
as well as the out
parameter, or should I create two separate procedures for each?
Int32 returnValue = 0;
Parameters parameters = new Parameters();
parameters.Add(new SqlParameter("@dateStart", dateStart != null ? (object)dateStart : DBNull.Value));
parameters.Add(new SqlParameter("@dateEnd", dateEnd != null ? (object)dateEnd : DBNull.Value));
SqlParameter out_recordCount = new SqlParameter("@recordCount", SqlDbType.BigInt);
out_recordCount.Direction = ParameterDirection.InputOutput;
out_recordCount.Value = recordCount;
parameters.Add(out_recordCount);
SqlParameter return_Value = new SqlParameter("@RETURN_VALUE", SqlDbType.Int);
return_Value.Direction = ParameterDirection.ReturnValue;
parameters.Add(return_Value);
dataReader = this.command.ExecuteReader("dbo.SelectDays", CommandType.StoredProcedure, parameters.ToArray());
if(out_recordCount.Value != DBNull.Value)
recordCount = Convert.ToInt64(out_recordCount.Value);
returnValue = Convert.ToInt32(return_Value.Value);
return returnValue;
The value for your output parameter is in the stream from SQLServer AFTER any results sets returned (I believe this is also true of the return value). That means you won't see the value until after you read all the rows from the DataReader (or close it I believe). So an output parameter that tells you the number of rows in the result set is of little use.
However, the code fragment below demonstrates the sequence of operations you should be using:
using(SqlConnection connection = new SqlConnection("[your connection string here]"))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.SelectDays";
command.Parameters.AddWithValue("@dateStart", dateStart != null ? (object)dateStart : DBNull.Value);
command.Parameters.AddWithValue("@dateEnd", dateEnd != null ? (object)dateEnd : DBNull.Value);
SqlParameter out_recordCount = new SqlParameter("@recordCount", SqlDbType.BigInt);
out_recordCount.Direction = ParameterDirection.InputOutput;
out_recordCount.Value = recordCount;
command.Parameters.Add(out_recordCount);
SqlParameter return_Value = new SqlParameter("@RETURN_VALUE", SqlDbType.Int);
return_Value.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(return_Value);
using(SqlDataReader reader = command.ExecuteReader())
{
while(reader.Read()) { /* do whatever with result set data here */ }
}
/* Output and return values are not available until here */
if (out_recordCount.Value != DBNull.Value)
recordCount = Convert.ToInt64(out_recordCount.Value);
returnValue = Convert.ToInt32(return_Value.Value);
return returnValue;
}
}
To get the values from OUTPUT parameters with SqlDataReader you can only after the reader will be closed.
So you need to add this code before you try to get the values
if(!dataReader.IsClosed)
dataReader.Close();
if(out_recordCount.Value != DBNull.Value)
recordCount = Convert.ToInt64(out_recordCount.Value);
returnValue = Convert.ToInt32(return_Value.Value);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With