Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C#中的输出参数和结果集读取SP?_C#_Sql Server 2005_Stored Procedures_Sqldatareader_Output Parameter - Fatal编程技术网

使用C#中的输出参数和结果集读取SP?

使用C#中的输出参数和结果集读取SP?,c#,sql-server-2005,stored-procedures,sqldatareader,output-parameter,C#,Sql Server 2005,Stored Procedures,Sqldatareader,Output Parameter,我创建了一个类似于此简化示例的存储过程: 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 SELEC

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

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()
方法后,尝试从输出变量读取值时,值为null

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

我做错了什么?

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

如果在读取结果集之前必须有count和sum,则必须放弃输出参数。只需使用您感兴趣的两个值生成一个普通结果集,然后购买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读取到末尾,然后检查输出参数,它们就会被设置。

您需要将读取器读取到末尾,输出参数位于TDS流的末尾,并且在结果集未被使用之前,客户端不会看到它们

如果在读取结果集之前必须有count和sum,则必须放弃输出参数。只需使用您感兴趣的两个值生成一个普通结果集,然后购买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直到结束,然后检查输出参数,它们将被设置。

正如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
}

正如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
}