SqlDataReader 获取特定的 ResultSet

SqlDataReader get specific ResultSet

当查询有 returns 多个结果时,我们使用 SqlDataReaderNextResult() 在它们之间进行迭代。这样我们就可以按顺序访问结果。

有没有办法以随机/非顺序方式访问结果。例如先跳到第三个结果,然后跳到第一个 e.t.c

我正在搜索是否有类似 rdr.GetResult(1) 的内容或解决方法。

自从有人问我 为什么 我想要这样的东西,

更新 13/6

虽然 gives a thoughtful explanation on why, shows the right directions for a workaround. The content of the link 在评论中说明了如何利用额外的 datasetasync 的方式工作。恕我直言,如果要编写通用解决方案,这将是可行的方法。但是,就我而言,我的解决方案基于数据的性质及其背后的逻辑。简而言之,(1)我使用 SqlDataReader 按顺序读取数据; (2)当我读取行中的第一个但逻辑结果集中的第二个时,我将一些我需要的数据存储在字典和集合中; (3) 当我读取行中的第三行时,但首先在逻辑 ResultSet 中,我正在遍历我之前构建的集合,并基于我正在构建最终结果的字典数据。

最终代码似乎比使用 async DataAdapter 更高效,更易于维护。然而,这是一个基于我的数据的非常具体的解决方案。

Provides a way of reading a forward-only stream of rows from a SQL Server database.

https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader(v=vs.110).aspx

您需要使用 DataAdapter 进行断开连接和非顺序访问。要使用它,您只需更改 ADO.NET 代码的一部分。

而不是

SqlDataReader sqlReader = sqlCmd.ExecuteReader();

你需要

DataTable dt = new DataTable();
SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlCmd);
sqlAdapter.Fill(dt);

如果您的 SQL returns 多个结果集,您将使用 DataSet 而不是 DataTable,然后访问 ds.Tables[index_or_name] 这样的结果集。

https://msdn.microsoft.com/en-us/library/bh8kx08z(v=vs.110).aspx

不,这是不可能的。原因很简单:如果一个批次 return 有多个结果,它必须 return 它们按顺序排列——声明 returns 结果集 #2 不 运行 在 return 的结果集 #1 之前,客户端也没有任何方式说 "please just skip that first statement entirely" (因为这可能对整个批次产生可怕的后果)。事实上,通常甚至没有任何方法可以判断一个批处理将产生多少结果集——所有这些都是在 运行 时间完成的,服务器事先不知道会发生什么。

由于在服务器端无法跳过或索引结果集,因此在客户端也没有任何有意义的方法。您可以随意忽略返回给您的结果集,但您仍然必须按顺序处理它们才能继续 - 一旦您继续前进,就无法返回。

有两种可能的全局解决方法:

  • 如果您处理所有数据并将其缓存在本地(例如,使用 DataAdapter),您可以随意在数据中来回移动,但这需要将所有数据保存在内存中。
  • 如果启用 MARS(多个活动结果集),即使第一个查询仍在处理中,您也可以执行另一个查询。这确实需要将您现有的单个批处理代码拆分为单独的语句(如果您真的根本无法更改 SQL 的任何内容,则不是一个选项),但您可以随意查看结果集(没有缓存)。不过,您仍然不可能在单个结果集中 "go back"。