背景
今天审核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,转载请注明作者出处】