我有一个SQL Server存储过程,它返回多个结果。存储过程的主体可能如下所示:
SELECT * FROM tableA;
SELECT * FROM tableB;
SELECT * FROM tableC;
在这种情况下,存储过程返回3个结果集。其他存储过程可能返回例如1,0或任何数量的结果集。每个结果集中可能包含0行或更多行。加载这些内容时,我需要调用IDataReader.NextResult()
来在结果集之间导航。
如何在C#中可靠地获取结果集(不是行数)?
答案 0 :(得分:7)
似乎没有直接计算IDataReader
中结果计数的属性或方法。该接口更倾向于以增量/流式方式使用。因此,要计算返回的结果集数量,请在每次调用IDataReader.NextResult()
时递增计数器,并在消耗数据时返回true
。
然而,有一个问题。该
IDataReader.NextResult()
州的文档:
默认情况下,数据读取器位于第一个结果上。
请考虑以下情况:
IDataReader.NextResult()
会返回false
。IDataReader.NextResult()
会返回false
。IDataReader.NextResult()
的第二次通话会返回false
。只要至少有一个结果集,您就可以看到我们有足够的信息来计算结果集的数量。这将是IDataReader.NextResult()
返回true
加一。
要检测是否有0个结果集,我们使用读者的另一个属性:IDataRecord.FieldCount
。该属性的文档声明:
当未定位在有效记录集中时,0;否则,当前记录中的列数。默认值为-1。
因此,我们可以在首次打开阅读器时读取该字段,以确定我们是否在有效的结果集中。如果该命令不生成结果集,则阅读器上的IDataRecord.FieldCount
值最初将小于1.如果该命令至少生成一个结果集,则该值最初为正数。这假设结果集不可能有0列(我认为你可以用SQL假设,不确定)。
所以,我会使用类似下面的内容来计算结果集的数量。如果您还需要保存数据,则必须将该逻辑插入到此:
using (var reader = command.ExecuteReader())
{
var resultCount = 0;
do
{
if (reader.FieldCount > 0)
resultCount++;
while (reader.Read())
{
// Insert logic to actually consume data here…
// HandleRecordByResultIndex(resultCount - 1, (IDataRecord)reader);
}
} while (reader.NextResult());
}
我已使用System.Data.SqlClient
和命令PRINT 'hi'
(0结果集),SELECT 1 x WHERE 1=0
(1个结果集)和SELECT 1 x WHERE 1=0; SELECT 1 x WHERE 1=0
(2个结果集)对此进行了测试
答案 1 :(得分:6)
使用DataReader.NextResult
将读者推进到下一个结果集。:
using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
using (var cmd = new SqlCommand("SELECT * FROM TableA; SELECT * FROM TableB; SELECT * FROM TableC;", con))
{
con.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
int firstIntCol = rdr.GetInt32(0); // assuming the first column is of type Int32
// other fields ...
}
if (rdr.NextResult())
{
while (rdr.Read())
{
int firstIntCol = rdr.GetInt32(0); // assuming the first column is of type Int32
// other fields ...
}
if (rdr.NextResult())
{
while (rdr.Read())
{
int firstIntCol = rdr.GetInt32(0); // assuming the first column is of type Int32
// other fields ...
}
}
}
}
}
}