【问题标题】:Possible to return an out parameter with a DataReader可以使用 DataReader 返回 out 参数
【发布时间】:2015-08-17 14:11:45
【问题描述】:

使用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?您如何将参数传递给命令?
  • 也许this 会有所帮助。
  • command 到底是什么?我不熟悉采用命令文本、类型和参数的 SqlCommand.ExecuteReader 的重载。

标签: c# sql-server


【解决方案1】:

输出参数的值在返回任何结果集之后来自 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() 需要在方法之外完成。我决定将这两种方法分开。
【解决方案2】:

要使用 SqlDataReader 从 OUTPUT 参数中获取值,您只能在阅读器关闭之后。

所以您需要在尝试获取值之前添加此代码

if(!dataReader.IsClosed)
    dataReader.Close(); 
 if(out_recordCount.Value != DBNull.Value)
     recordCount = Convert.ToInt64(out_recordCount.Value);
 returnValue = Convert.ToInt32(return_Value.Value);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-12
    • 2013-06-28
    • 1970-01-01
    • 2021-11-19
    • 2013-06-19
    • 2011-10-24
    • 1970-01-01
    • 2014-01-12
    相关资源
    最近更新 更多