如何在C#中读取存储过程多个SELECT语句返回的多个结果值
问题原因
你遇到的System.OutOfRangeException异常是因为存储过程中每一条返回结果集的SELECT语句,都会对应DataReader中的一个独立结果集,而非在现有结果集里新增列。你新增的统计查询是第三个独立结果集,你尝试在第二个结果集(全量总数)中读取索引为1的列,自然会因为第二个结果集只有1列而报越界错误。
解决方案
步骤1:确认存储过程的结果集输出顺序
确保你的存储过程最终的输出顺序和C#读取顺序完全匹配,参考示例:
-- 1. 构建临时表(无结果集返回) SELECT colA, colB, colC INTO #MyTable -- 2. 第一个结果集:返回业务数据(供Materialize读取前10条) SELECT colA, colB, colC FROM #MyTable -- 3. 第二个结果集:返回全量数据总数 SELECT COUNT(*) from #MyTable -- 4. 第三个结果集:返回新增的符合条件的统计值 SELECT COUNT(*) from #MyTable WHERE colA = 'sample value'
步骤2:调整C#读取逻辑
在读完第二个结果集的全量总数后,再调用一次NextResult()切换到第三个结果集,读取索引为0的列即可:
int total = 0; int total2 = 0; // 新增的统计值变量 var command = _context.CreateStoreCommand( "dbo.mySP", CommandType.StoredProcedure, new SqlParameter("Param1", parameters.Param1), //... ); using (command.Connection.CreateConnectionScope()) { using (var reader = command.ExecuteReader()) { // 读取第一个结果集:业务数据 result = new Materializer<MyType>() .Materialize(reader) .ToList(); // 切换到第二个结果集:全量总数 if (reader.NextResult() && reader.Read()) { total = reader.GetInt32(0); } // 新增:切换到第三个结果集:符合条件的统计值 if (reader.NextResult() && reader.Read()) { total2 = reader.GetInt32(0); } } }
额外注意事项
- 结果集的读取顺序必须和存储过程的输出顺序完全一致,不能跳过或调换顺序
- 每个独立结果集的列索引都从0开始计算,和其他结果集的列数无关
内容的提问来源于stack exchange,提问作者user2687153
相关产品推荐
相关产品推荐

