能否使用DataReader返回一个out参数

16
使用ExecuteReader我能够返回一个DataReader,但是out参数返回了0。
使用ExecuteNonQuery我能够检索到正确值的out参数,但是ExecuteNonQuery没有返回DataReader
以下是上下文提供的过程:

SQL查询:

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

有没有一种方法可以同时返回DataReaderout参数,或者我应该为每个参数创建两个单独的过程?

C#代码:

     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;

你能展示一下你的C#代码吗?你是否将“CommandType”设置为“CommandType.StoredProcedure”?你是如何传递参数给命令的? - juharr
也许这个链接能够帮到你。 - juharr
“command”是什么?我不熟悉SqlCommand.ExecuteReader的重载,它需要命令文本、类型和参数。 - juharr
2个回答

17

你的输出参数的值在SQLServer返回所有结果集之后,也就是说在读取DataReader中的所有行(或关闭它,我认为这也适用于返回值)之前你不会看到该值。因此,一个输出参数如果告诉你结果集中的行数是没有什么用处的。

然而,下面的代码片段展示了你应该使用的操作顺序:

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;
  }
}

感谢您的时间,但我需要返回读取器。上述解决方案可以工作,但是Read()需要在方法之外完成。我决定将这两个方法分开。 - Pierre Nortje
这很有帮助。需要额外执行reader.NextResult()使读取器关闭并填充参数值。 - Stevie

3
使用SqlDataReader获取输出参数的值,必须在读取器关闭后才能进行。因此,在尝试获取这些值之前,您需要添加以下代码。
if(!dataReader.IsClosed)
    dataReader.Close(); 
 if(out_recordCount.Value != DBNull.Value)
     recordCount = Convert.ToInt64(out_recordCount.Value);
 returnValue = Convert.ToInt32(return_Value.Value);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接