设为首页 收藏本站
查看: 688|回复: 0

[经验分享] 你会用微软sql server的Update语句的一个扩展功能,还有如何绕过它的一个bug(首发)吗?

[复制链接]

尚未签到

发表于 2015-6-30 11:19:11 | 显示全部楼层 |阅读模式
  微软Sql server的Update语句,有个不错的扩展功能,通过允许变量赋值,可在语句中嵌入复杂的逻辑计算,从而让本来需要一个Select 加一个Update语句的段子,被优化成只需一个update语句。这对性能提高有不小的好处.但是,这项功能有个尚未报告且不易注意的bug.
  举例来说,下述形式都是合法的:
  Update table1 set column1 = expr1, @var1 = expr2, @var2= column2 = expr3, ...  where where_condition
  
  为了说更透彻的说明问题, 看下面的语句:



UPDATE dbo.TableX
SET @oldDesc = Description, @OldApr = ApproveBits,
@NewApr = case when @OldApr & @txtCheck  0 and @oldDesc  @Description then @OldApr & @txtMask2
else @OldApr end,
@NewApr = (case when @NewApr & @rateCheck = 0 then @NewApr
when @protectlevel >= XRate then @NewApr | @rateBit
else @NewApr & @rateMask end),
ApproveBits = @NewApr, --don't as @NewApr=ApproveBits=
-- parse incorrectly due to a bug
@dateSet = case when LastModified is null and (@NewApr = 0 or @NewApr = 3) then 1 else 0 end,
LastModified = case when @dateSet = 1 then @pnewDate else LastModified end,...
WHERE ...
  
  
  你看了上面的代码会不会晕? DSC0000.gif . 在Update Clause中, 标准的sql只允许对数据库表的列赋值.由于微软sql的这一扩展, 允许对变量赋值, 再和case 语句组合起来, 就可以实现相当复杂的逻辑计算.如果没有这些,一个Update语句就能做完的事情,就需要一个Select加一个Update语句才能实现.上面的那个例子,全面的利用了这一功能,从而实现对性能的提高和优化.
  
  你如果看到上面的代码会晕,那是因为,微软本身提供的文档并没有完整透彻的说明这一功能,经过我个人的测试和总结,补充以下重要条款:
  1.由于允许被赋值的是变量,可以在update中嵌入复杂的逻辑计算,并且可以让本来需要一个select 加一个update语句的段子,被优化成只需要一个update语句的段子。这对性能提高有不小的好处。
  2。@var2= column2 = expr3, 等同于: @var2= expr3, column2 = expr3
  不同于“@var2= column2, column2 = expr3" 或者“column2 = expr3, @var2= column2", 后两种形式都是把column2的旧值赋予了@var2.
  3. 形式: column2 = @var2= expr3, 非法.
  由于可能出现嵌套引用,所以必须知道在赋值时的优先级,规则如下,
  4. 变量赋值相对列赋值优先.
  5. 如果都是变量赋值,那么更靠左边的优先.
  6. 在赋值表达式右边出现的变量的值是该变量的当前值.
  7. 在赋值表达式右边出现的列的值永远是该列的旧值, 与在update语句中的次序无关.
  
  目前, 这个扩展功能有一个bug, 就是,在下面的形式中:
  "...set @var2 = expr1, @var2= column2 = expr2,... ",
  你会想当然地认为@var2最后的值是expr2, 但是,由于这个bug,实际上, var2最后的值是expr1.
  为了绕开这个bug, 你可以把上面重写成下面的形式:
  @var2 = expr1, @var2= expr2, column2 = @var2
  
  这里介绍的都是个人精炼的,在微软的文献中找不到的,值得收藏呵.
  weibo:JohnXhark

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-81890-1-1.html 上篇帖子: SQL Server 2008中的Pivot和UnPivot 下篇帖子: SQL SERVER索引优化系列之一:工作原理&聚簇索引|非聚簇索引
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表