尝试从存储过程中加载第二个结果集。

4

我有一个客户设置,使用存储过程从其SQL Server数据库返回数据。

这些存储过程都是相同的 - 它们接受一堆输入参数,并返回:

  • 第一个仅是一个包含结果代码(类型为INT)的单行、单列 - 成功为0,否则为其他值;如果该值为0,则存在第二个结果集,其中包含实际数据

  • 第二个结果集可以是任何东西 - 任意数量的列和行

我正在尝试创建一种“通用”的方法来与此系统进行交互,我的尝试是这样的:

  • 创建一个类,该类需要存储过程名称和输入参数
  • 返回类型包含一个 ErrorCode INT 属性以及一个 DataTable results 属性

然而,我在使用ADO.NET和SQL Server 2008 R2时遇到了问题。

我的代码简化为:

public MyResultType CallService(string procedureName, MyParameters parameters)
{
     MyResultType result = new MyResultType { ErrorCode = 0 };

     using (SqlConnection conn = new SqlConnection(_connectionString))
     using (SqlCommand cmd = new SqlCommand(procedureName, conn))
     {
         cmd.CommandType = CommandType.StoredProcedure;
         SetupParameters(cmd, parameters);

         // open connection, execute the stored procedure
         conn.Open();

         using (SqlDataReader rdr = cmd.ExecuteReader())
         {
             // get the first result set - the status code, one row, one column of type INT
             while (rdr.Read())
             {
                 result.ErrorCode = rdr.GetInt32(0);
             }

             // if we got a "0" (success) -> go to the next result set and load it into the table
             if(result.ErrorCode == 0 && rdr.NextResult())
             {
                 result.ResultTable = new DataTable();
                 result.ResultTable.Load(rdr);

                 int colCount = result.ResultTable.Columns.Count;
                 int rowCount = result.ResultTable.Rows.Count;
              }

              rdr.Close();
         }

         conn.Close();
   }

   return result;
}

我的问题是:调用存储过程没有问题,错误代码=0被正确捕获,数据表被创建且列数与预期值相同,但是没有行加载...
我已经尝试了我能想到的一切方法来将这些行加载到数据表中-但是不成功。当然,如果我在SQL Server Management Studio中执行这个完全相同的存储过程,一切都很顺利,我得到我的ErrorCode=0以及18列和5行的结果集-没有问题...
我缺少什么?有人能找出代码中的问题吗?为什么第二个结果集的行没有加载(但好像检测到了列)?

列数是预期值,"result"表格也被适当地创建(除了没有行),这表明存储过程从"控制台"(SQL Server Management Studio)和你的ADO.Net代码中调用时存在一些差异。特别是存储过程需要哪些参数?在上面的代码片段中,你引用了但没有公开它们作为"参数"。 - hardmath
可以通过运行分析器跟踪来检查这个。 - Tom Hunter
2个回答

4

这段代码已经可以正常使用 - 问题出在我从C#中调用和在SQL Server管理工具中调用时的区别: NULL处理。

我将一些输入参数设置为int,因此向存储过程提供了一个0值,而实际上如果该值未定义,它应该得到一个NULL......

愚蠢的新手错误.....对不起大家! 感谢您的指导!


1

DataTable.Load方法会隐式调用NextResult方法,因此与您的显式调用结合使用时,它会推进到不存在的结果集。如果您想使用DataTable.Load 循环并自己填充数据表,则应删除自己对NextResult的调用。


1
DataTable.Load 在加载结果集后会调用 NextResult 方法.... 如果我不在那里放置 .NextResult(),那么我将再次加载第一个结果集(只有一行,一列)。我已经测试过了。 - marc_s

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