【问题标题】:DataReader already open error when trying to run two queries尝试运行两个查询时 DataReader 已打开错误
【发布时间】:2022-01-14 17:07:21
【问题描述】:

我有几个查询需要运行一个到链接服务器,另一个不是这样

    Dim InvestorLookup As String = "DECLARE @investor varchar(10), @linkedserver varchar(25), @sql varchar(1000) "
    InvestorLookup += "SELECT @investor = '" & investor & "', @linkedserver = '" & db & "', "
    InvestorLookup += "@sql = 'SELECT * FROM OPENQUERY(' +@linkedserver + ', ''SELECT * FROM db WHERE investor = ' + @investor + ' '')' EXEC(@sql)"
    Dim queryInvestorLookup  As SqlCommand = New SqlCommand(InvestorLookup , conn)

    Dim BondNoDR As SqlDataReader = queryInvestorLookup.ExecuteReader()

    Dim PasswordCheck As String = "DECLARE @investor varchar(10), @password varchar(20), @linkedserver varchar(25), @sql varchar(1000) "
    PasswordCheck += "SELECT @investor = '" + investor + "', @password = '" + password + "', @server = '" + db2 + "', "
    PasswordCheck += "@sql = 'SELECT * FROM @server WHERE investor = @investor AND password = ' + @password + ' '' EXEC(@sql)"
    Dim queryPasswordCheck As SqlCommand = New SqlCommand(PasswordCheck, conn)

    Dim PasswordDR As SqlDataReader = queryPasswordCheck.ExecuteReader()

据我调试,查询都按应有的方式运行,但我得到了错误

There is already an open DataReader associated with this Command which must be closed first.

是否可以在两个不同的 DataReader 中运行两个查询。我需要稍后引用每个 DataReader 并从中选择值。

【问题讨论】:

    标签: asp.net sqldatareader


    【解决方案1】:

    默认情况下,不可能同时打开两个 SqlDataReader 共享同一个 SqlConnection 对象。您应该在调用第二个 (queryPasswordCheck) 之前关闭第一个 (queryInvestorLookup)。

    从设计和性能的角度来看这会很好,因为 .NET 的建议是每个非托管资源(如数据库访问)尽可能晚地打开并尽早关闭。

    另一种方法是启用 MARS,但它仅适用于 Sql2005 及更高版本。

    第三种解决方案是使用相同的 SqlDataReader 发出两个查询,然后使用 NextResults() 方法进行导航。

    【讨论】:

    • 其实我相信 MARS 支持是在 SQL 2005 中引入的
    • 如何知道我在哪个 SQL Server 上?
    • @tucaz 我添加了MultipleActiveResultSets=True 位,它没有错误,这表明它确实支持,但我仍然像以前一样收到打开数据读取器错误
    • 您是否遇到同样的错误?根据这篇文章 (msdn.microsoft.com/en-us/library/ms131686.aspx),唯一需要启用它的就是将信息放在连接字符串上(就像你所做的那样),你应该很高兴。但是,我建议您采用我在回答中提供的其他两种方法之一,因为它们会为您节省一些资源。
    【解决方案2】:

    如果您使用的提供程序支持它,您可以通过将 MultipleActiveResultSets=True 添加到您正在使用的连接字符串来启用 MARS(多个活动结果集)。

    【讨论】:

      【解决方案3】:

      默认情况下,您不必在同一连接上打开 dataReader。因此,您可以得到一个结果,将其填充到 DataTable 中,然后得到另一个结果。或者你可以打开 MARS

      ADO.NET Multiple Active Resut Sets

      【讨论】:

      • 我怎样才能将它“塞入”数据表中?
      • 您可以使用适配器自动将 DbDataReader 放入 DataTable 或 DataSet。本质上,您创建一个适配器实例并为其分配 SelectCommand(用于您的 select 语句的命令),然后调用适配器上的 Fill 方法msdn.microsoft.com/en-us/library/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      相关资源
      最近更新 更多