【问题标题】:Reading SP with output parameters and result set in C#?在 C# 中读取带有输出参数和结果集的 SP?
【发布时间】:2009-09-01 21:22:26
【问题描述】:

我已经创建了一个类似于这个简化示例的存储过程:

CREATE PROCEDURE dbo.sp_MyStoredProcedure
    @Var1 INT OUTPUT,
    @Var2 DECIMAL(10,2) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    SELECT
        @Var1 = COUNT(*),
        @Var2 = SUM(TranAmount)
    FROM
        MyTable

    SELECT * FROM MyTable
END

当我在调用SqlCommand 对象的ExecuteReader() 方法后尝试从输出变量中读取值时,这些值为空。

string MyConnString = string.Empty;
SqlConnection MyConn = new SqlConnection(MyConnString);
SqlCommand MyCmd = new SqlCommand("sp_MyStoredProcedure", MyConn);
MyCmd.CommandType = CommandType.StoredProcedure;
MyCmd.Parameters.Add(new SqlParameter("@Var1", SqlDbType.Int));
MyCmd.Parameters.Add(new SqlParameter("@Var2", SqlDbType.Decimal);
MyCmd.Parameters[0].Direction = ParameterDirection.Output;
MyCmd.Parameters[1].Direction = ParameterDirection.Output;
SqlDataReader dr = MyCmd.ExecuteReader(CommandBehavior.CloseConnection);
int Var1 = Convert.ToInt32(MyCmd.Parameters[0].Value);
decimal Var1 = Convert.ToDecimal(MyCmd.Parameters[1].Value);

我做错了什么?

【问题讨论】:

    标签: c# sql-server-2005 stored-procedures sqldatareader output-parameter


    【解决方案1】:

    您需要阅读阅读器直到结束,输出参数位于 TDS 流的末尾,客户端在未使用结果集之前不会看到它们。

    如果您必须在读取结果集之前获得计数和总和,则必须放弃 OUTPUT 参数。只需生成一个包含您感兴趣的两个值的普通结果集,然后购买 SELECT * 结果集。然后使用 SqlDataReader.NextResult() 读取客户端中的两个结果集。

    更新

    我的意思是有两个结果集:

    CREATE PROCEDURE dbo.sp_MyStoredProcedure    
    AS
    BEGIN    
      SET NOCOUNT ON;    
      SELECT COUNT(*) as cnt, SUM(TranAmount) as sum_ta
      FROM MyTable
      SELECT * FROM MyTable
    END
    

    和客户:

    string MyConnString = string.Empty;
    SqlConnection MyConn = new SqlConnection(MyConnString);
    SqlCommand MyCmd = new SqlCommand("sp_MyStoredProcedure", MyConn);
    MyCmd.CommandType = CommandType.StoredProcedure;
    using(SqlDataReader dr = MyCmd.ExecuteReader(CommandBehavior.CloseConnection))
    {
      while(dr.Read())
      { 
         count = dr["cnt"];
         sum = dr["sum_ta"];
      }
      dr.NextResult();
      while(dr.Read())
      {
        // process MyTable row here
      }
    }
    

    请注意,如果您的 C# 代码在使用数据读取器之前不需要输出参数的值,您确实不需要需要这样做。您可以简单地读取 SqlDataReader 直到结束,然后检查输出参数,它们将被设置。

    【讨论】:

      【解决方案2】:

      正如 Remus 所说,如果您首先需要它,那么您需要重新解决您的查询方式。为什么没有两个独立的程序?这将是抽象的最佳解决方案。

      否则,您可以在同一批次中执行两条 SQL 语句

      SELECT COUNT(*) AS VAR1, SUM(TranAmount) AS VAR2 FROM MyTable
      SELECT * FROM MyTable
      

      然后当你调用 ExecuteReader

      SqlDataReader dr = MyCmd.ExecuteReader(CommandBehavior.CloseConnection);
      while (dr.read())
      {
          var1 = dr["Var1"];
          var2 = dr["Var2"];
      }
      
      dr.NextResult();
      
      while (dr.read())
      {
         // blah blah blah code
      }
      

      【讨论】:

        猜你喜欢
        • 2013-01-18
        • 1970-01-01
        • 1970-01-01
        • 2011-08-12
        • 2021-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多