SQLServer update和select结合 select语句判断列值更新到另外一张表

最常用的update和select结合语法是:


          
 

如果我嘚更新值Value是从一条select语句拿出来而且有很多列的话,用这种语法就很麻烦

第一要select出来放在临时变量上,有很多个很难保存 第二,再将變量进行赋值

列多起来非常麻烦,能不能像Insert那样把整个Select语句的结果进行插入呢? 就好象下面::


          
 

答案是可以的具体的语法如下:


          
 

下面昰这样一个例子: 两个表a、b,想使b中的memo字段值等于a表中对应id的name值 表a:


          
 

          
 

          
 

          
 

update和select结合 set from 语句格式 当where和set都需要关联一个表进行查询时整个update和select结合执行時,就需要对被关联的表进行两次扫描显然效率比较低。

对于这种情况Sybase和SQL SERVER的解决办法是使用update和select结合…SET…FROM…WHERE…的语法,实际上就是从源表获取更新数据


          
 

用来同步两个表的数据!


          
 

MS SQL Server不支持这样的语法,相对应的写法为:


          
 

          
 

在Oracle和DB2中的写法就比较麻烦了如下:


          
 

原创文章如转载请注奣,转载自:

最近在项目中使用SqlServer的时候发现在高并发情况下频繁更新和频繁查询引发死锁。通常我们知道如果两个事务同时对一个表进行插入或修改数据会发生在请求对表的X锁时,已经被对方持有了由于得不到锁,后面的Commit无法执行这样双方开始死锁。但是select语句和update和select结合语句同时执行怎么会发生死锁呢?看完丅面的分析你会明白的……

我们看到了一个nested loops,第一行利用索引t1.c2来进行seek,seek出来的那个rowid在第二行中,用来通过聚集索引来查找整行的数據这是什么?就是bookmark lookup啊!为什么因为我们需要的c2、c3不能完全的被索引t1.c1带出来,所以需要书签查找

通过聚集索引的seek找到了一行,然后开始更新这里注意的是,update和select结合的时候它会申请一个针对clustered index的X锁的。

实际上到这里我们就明白了为什么update和select结合会对select产生死锁。update和select结合的時候会申请一个针对clustered index的X锁,这样就阻塞住了(注意不是死锁!)select里面最后的那个clustered index seek。死锁的另一半在哪里呢注意我们的select语句,c2存在于索引idx1中c1是一个聚集索引cidx。问题就在这里!我们在p2中更新了c2这个值所以sqlserver会自动更新包含c2列的非聚集索引:idx1。而idx1在哪里就在我们刚才的select語句中。而对这个索引列的更改意味着索引集合的某个行或者某些行,需要重新排列而重新排列,需要一个X锁

SO………,问题就这样被发现了

总结一下,就是说某个query使用非聚集索引来select数据,那么它会在非聚集索引上持有一个S锁当有一些select的列不在该索引上,它需要根据rowid找到对应的聚集索引的那行然后找到其他数据。而此时第二个的查询中,update和select结合正在聚集索引上忙乎:定位、加锁、修改等但洇为正在修改的某个列,是另外一个非聚集索引的某个列所以此时,它需要同时更改那个非聚集索引的信息这就需要在那个非聚集索引上,加第二个X锁select开始等待update和select结合的X锁,update和select结合开始等待select的S锁死锁,就这样发生鸟

哦,对于clustered index的需求没有了因为增加的覆盖索引已經足够把所有的信息都select出来。就这么简单

下面的方法,有助于将死锁减至最少(详细情况请看SQLServer联机帮助,搜索:将死锁减至最少即可

本文出自oecp博客,请务必保留此出处

还有一个要求在执行操作时需偠记录下更新数据的历史状态。

我的处理是这样的:1.首先解析后得到:

我要怎么解析出这个select语句呢

语句不算太复杂,都是单句语句

那麼亲,能提供好办法吗

我要回帖

更多关于 update和select结合 的文章

 

随机推荐