说明:一个带有update的循环的代码。很简单,但是在QQ群里问了,应该说是很少有人注意这个问题,也就是很少有人真的理解SQL中的Update。
代码如下:
if object_id('tempdb..#TB') is not null drop table #TB go --创建的是临时表 create table #TB ( ID int ) --插入5条记录 insert into #TB (ID) select 1 union all select 2 union all select 3 union all select 4 union all select 5 --查看记录 select * from #TB go --代码1 declare @i int set @i = 1 while @i < 5 begin update #TB set ID = ID,@i = @i + 1 select @i end go --代码2 declare @i int set @i = 1 while @i < 5 begin update #TB set ID = ID set @i = @i + 1 select @i end
从代码看无非就是建立了一个临时表,插入5条记录,然后代码1和代码2没有太大的差别,初次看见认为2次的循环都是4次,@i的结果应该都是5,如果你这么想,劝你还是把代码执行一遍吧,自己先想想,你的认为是错的。
正确的结果是:
代码1的循环次数1次,@i的结果6
代码2的循环次数4次,@i的结果5
看到这里,在好好的回去理解下代码,尤其是理解下update,然后再看后面的解释。
代码解释:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
两端代码的区别无非是在update这一行,代码1将2条小语句写在一行上面,而代码2分两行写了,这就是问题的所在。 代码1执行分析: @i=1 While(@i <5) { 通过循环判断 执行update,因为Update是修改ID字段的记录,记录数5条,则Update这行的代码执行5次,所以@i = @i + 1也连带的执行5次,完毕后,@i=6 输出@i 循环判断(@i <5)false跳出 } 说以,代码1的循环次数为1,但是@i=6 代码2执行分析: @i=1 While(@i <5) { 通过循环判断 执行update,因为Update是修改ID字段的记录,记录数5条,则Update这行的代码执行5次,但是代码2该行没有@i = @i + 1所以完毕后,@i=1 @i = @i + 1,@i = 2 输出@i 循环判断(@i <5)true,再次执行循环,知道false } 说以,代码2的循环次数为4,但是@i=5
参考引用:对于这种情况,我只能猜测是update本身的机制。对于代码1,每一条影响记录,那么便执行一次@i = @i + 1。所以在一次循环里面就执行了5次,达到了while的阀值,跳出循环。
参考文献:http://www.cnblogs.com/Gin-23333/p/4127453.html