update的顺序

背景

今天审核SQL语句,无意中看到2句update写法很奇怪:

update tb set weekNum = weekNum +dayNum where dayNum >0

update tb set dayNum =0 where dayNum >0

 

这样写法的原因主要是对SqlServer等数据库的不熟悉,感觉放在一起更新不大靠谱。其实完全可以合并在一起的。我们可以借助执行计划,看看实际的处理流程是怎么样的?

 

-- 切换到临时库,创建测试表

use tempdb

go

 

create table TestUpdate

(id int not null

 ,CurrNums int null

 ,DayNums int null

 ,MonthNums int null)

 

-- 插入测试数据

insert into TestUpdate

(id,CurrNums,DayNums,MonthNums)

select 1,1,10,100

    union all

select 2,2,20,200

    union all

select 3,3,30,300

    union all

select 4,4,40,400

    union all

select 5,5,50,500

 

-- 检查数据

select * from TestUpdate

/*

 

id          CurrNums DayNums     MonthNums

----------- -------- ----------- --------------------

1           1        10          100

2           2        20          200

3           3        30          300

4           4        40          400

5           5        50          500

 

(5 行受影响)

*/

         【出自blog.csdn.net/jerrynet,转载请注明作者出处】

--查看更新语句的执行计划

set   showplan_text   on

 

update TestUpdate

set DayNums=DayNums+CurrNums

    ,MonthNums=MonthNums+DayNums+CurrNums

    ,CurrNums=0

 

--部分执行计划结果

     |--Compute Scalar(DEFINE:(         [Expr1004]=[tempdb].[dbo].[TestUpdate].[DayNums]+[tempdb].[dbo].[TestUpdate].[CurrNums]

    [Expr1005]=[tempdb].[dbo].[TestUpdate].[MonthNums]+[tempdb].[dbo].[TestUpdate].[DayNums]))

 |--Table Update(OBJECT:([tempdb].[dbo].[TestUpdate]), SET:(

           [tempdb].[dbo].[TestUpdate].[DayNums] = [Expr1004]

           [tempdb].[dbo].[TestUpdate].[MonthNums] = [Expr1005]

           [tempdb].[dbo].[TestUpdate].[CurrNums] = [@1]))

 

--关闭设置并真正执行,查看结果

set   showplan_text   OFF

 

update TestUpdate

set DayNums=DayNums+CurrNums

    ,MonthNums=MonthNums+DayNums+CurrNums

    ,CurrNums=0

   

SELECT * FROM TestUpdate

   

/*

id          CurrNums    DayNums     MonthNums

----------- ----------- ----------- -----------

1           0           11          111

2           0           22          222

3           0           33          333

4           0           44          444

5           0           55          555

 

(5 row(s) affected)

 

*/

 

这里重点看下DEFINE部分和SET部分。中间定义了2个变量:[Expr1004] 和 [Expr1005],而CurrNums列则做了参数化处理[@1]。3个字段的更新其实是并行在一次操作里面完成的,所以这里可以放心的把2个语句合并起来。

    最终结果里面的CurrNums列全部已经复位成0了。

【出自blog.csdn.net/jerrynet,转载请注明作者出处】

作者: alen88   发布时间: 2010-09-16