0
 protected void btnFetch_Click(object sender, EventArgs e)
    {

    SqlConnection con = new SqlConnection(Helper.ConStr);
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = con;
    cmd.CommandText = "select * from emptable";
    con.Open();
    SqlDataReader dr = cmd.ExecuteReader();
    gv1.DataSource = dr;
    gv1.DataBind();

    dr.NextResult();

    **while (dr.Read())**//It is returning the value as false!
    {
        SqlCommand cmd1 = new SqlCommand();
        cmd1.CommandText = "select * from table1";
        Response.Write(dr[0]);
        Response.Write(dr[1]);
    }
    con.Close();
 }

我很困惑为什么,数据读取器选择一个“选择语句”,读取它并将其绑定到 Gridview 但是当涉及到使用下一组“选择语句”时,数据读取器不做任何事情. dr.Read()变成false.

请向我解释为什么会发生这种情况?

4

5 回答 5

2

数据读取器仅向前。这意味着您只能读取所有行一次。

因此,当您绑定 GridView 时,它将在数据读取器中移动,直到Read()返回 false(以便能够填充所有行)。

因此,当您尝试调用循环时,reader它已经位于记录集的末尾。

这在MSDN中有详细说明。

更新:

如果您向@Petoj 显示的那样添加了多个 SELECT 语句,则该NextResult()方法用于选择下一个结果。Command.CommandText因此,它对您的代码没有任何影响。

于 2013-03-28T15:19:23.373 回答
1

试试这个

 protected void btnFetch_Click(object sender, EventArgs e)
 {

    SqlConnection con = new SqlConnection(Helper.ConStr);
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = con;
    cmd.CommandText = "select * from emptable;select * from table1";
    con.Open();
    SqlDataReader dr = cmd.ExecuteReader();
    gv1.DataSource = dr;
    gv1.DataBind();

    dr.NextResult();

    while (dr.Read())
    {
        Response.Write(dr[0]);
        Response.Write(dr[1]);
    }
    con.Close();
 }
于 2013-03-28T15:19:46.847 回答
1

您不需要NextResultdr.NextResult();将读者推进到下一批:

using (var myCon = new SqlConnection(Helper.ConStr))
using (var selectCommand = new SqlCommand("select * from emptable", myCon))
{
    myCon.Open();
    using (var dr = selectCommand.ExecuteReader())
    {
        while (dr.Read()) 
        {
            // ...
        }
    }
}

因此,如果您选择两个表,您可以使用它NextResult来获取下一个,例如:

"select * from emptable; select * from otherTable"

通常你不需要使用这个方法,因为ExecuteReader已经返回了第一批。

请注意,我使用using-statement来确保所有非托管资源都在它的末尾被处理,即使在出现异常的情况下也是如此。您应该尽可能使用它。这适用于每个实现的对象IDisposable(如果using在不可能的情况下尝试使用,则会出现编译器错误)。

SqlConnection.Dispose也会关闭连接,因此您不需要手动执行此操作(这适用于所有连接类型)。

MSDN

通常,当您使用一个IDisposable对象时,您应该在 using 语句中声明和实例化它。using 语句以正确的方式调用对象的 Dispose 方法。在 using 块中,对象是 只读的,不能修改或重新分配。using 语句可确保调用 Dispose,即使在调用对象上的方法时发生异常也是如此。

于 2013-03-28T15:21:08.407 回答
0

dr.NextResult();如果您的查询Reference中有多个 select 语句,则可以使用。
您的表中只有一个选择语句

cmd.CommandText = "select * from emptable";

因此,如果您必须使用多个 select 语句,那么在命令文本中您应该有多个 select 语句,如下所示

cmd.CommandText = "select * from emptable;select * from table1";
于 2013-03-28T15:20:54.963 回答
0

您必须在 sql server 中编写存储过程

CREATE PROCEDURE selectFromTwoTables AS BEGIN BEGIN TRANSACTION

SELECT * FROM 空

选择 * 从表 1

IF(@@error = 0) -- 如果发生任何错误,事务将回滚。否则提交 COMMIT TRANSACTION ELSE ROLLBACK TRANSACTION END

在 c# SqlCommand cmd = new SqlCommand("selectFromTwoTables", conn); cmd.CommandType = CommandType.StoredProcedure;

于 2013-03-28T16:12:29.630 回答