2

当您使用 SqlDataReader 时,返回集是否完全由 ExecuteReader 步骤确定,或者您是否可以通过在读取时写入源表来影响您获得的结果?这是一个非常粗糙的伪代码示例。

sc = new SqlCommand("select * from people order by last, first",db) ;
sdr = sc.ExecuteReader() ;

while (sdr.read())
{
    l = (string) sdr["last"] ;
    k = (string) sdr["key"] ;
    if (l.Equals("Adams")) 
    {
       sc2 = new SqlCommand("update people set last = @nm where key = @key") ;
       sc2.Parameters.Add(new SqlParameter("@nm", "Ziegler"));
       sc2.Parameters.Add(new SqlParameter("@key", k));
       sc2.ExecuteNonQuery() ;
    }
}

我在其他环境中看到了很多由于写入您正在阅读的表而导致的错误。这里记录 k 从列表的顶部 (Adams) 被撞到底部 (Ziegler)。我假设(哈!)SqlDataReader 是免疫的。真的?错误的?

4

4 回答 4

4

这取决于您的事务隔离级别或其他锁定提示,但 iirc 默认情况下从 sql server 中的表读取会锁定这些记录,因此您发布的代码将死锁(sc2 最终将超时)或更新将进入事务日志,在您的阅读器完成之前不会写入任何内容。我不记得我的头顶上是哪个。

于 2009-05-28T14:22:30.577 回答
1

我看到的一个问题是,当阅读器打开时,它拥有数据库连接,当阅读器打开时,没有其他东西可以使用它。所以唯一可能的方法是使用不同的数据库连接,它仍然取决于事务级别

于 2009-05-28T14:26:27.340 回答
0

如果您想假设读取的数据不会被这些更新改变,您是否可以将数据读取到临时对象容器中,然后在完成所有读取之后,然后进行更新?这会使问题变得没有意义。

当然,从“这到底是如何工作的”的角度来看,我确实发现这个问题很有趣。

于 2009-05-28T14:27:47.713 回答
0

如果您想在迭代查询结果时进行更新,您可以将其全部读入 DataSet。

我知道你没有问这个问题,而且我也知道这是伪代码,但请务必将你的 sc、sdr 和 sc2 变量包装在 using () 语句中,以确保它们被正确处理。

于 2009-05-28T14:30:47.690 回答