玖叶教程网

前端编程开发入门

数据库大师成长日记:update语句在多表匹配更新中的应用

朋友们,在我们写SQL更新语句时,经常需要基于一个表的值对另一个表进行匹配更新。这种更新方式与直接赋值类的更新不同,写法也会复杂一些,下面我基于实例说明多表匹配更新的常规写法和可能碰到的问题。

多表匹配更新的语法结构

我见过最多的是两种方式,一种方式是直接源于多表,通过where条件匹配的,语法大致如下:

update t1
set t1.字段=t2.字段
from 表1 t1, 表2 t2 
where 表之间的匹配条件

这种写法我用的不多,可能是我平时建表总存在各种关联,我比较习惯通过join方式匹配的方式,语法大致如下:

update t1
set t1.字段=t2.字段
from 表1 t1
inner join 表2 t2 on t1.字段=t2.字段
where 其它条件

我觉得第二种写法更加直观,更便于将两个表的关系暴露出来。我下面就以第二种方式为例,具体说说多表更新的做法。

准备数据

我通过两个表变量进行演示,创建和初始化数据的SQL脚本如下:

declare @t1 table(FID int identity(1,1), FName varchar(100),FSerial int)
declare @t2 table(FSerial int identity(1,1), FName varchar(100), FID int)
insert into @t1(FName) values('马云')
insert into @t1(FName) values('马化腾')
insert into @t1(FName) values('马云')
insert into @t1(FName) values('李彦宏')
insert into @t1(FName) values('马云')
insert into @t1(FName) values('刘强东')
insert into @t1(FName) values('马云')
select * from @t1
insert into @t2(FName) values('马云')
select * from @t2

数据展示如下:

单条匹配多表更新的具体写法

所谓单条匹配,就是待修改表的数据,只与条件匹配表实现一对一或多对一的关系。为什么我这里要分开说,等您看下一段落的时候就知道了。

针对表变量@t1和@t2,比如我们要更新@t1中的FSerial的值,条件是根据@t2中的FName与@t1中的FName相同,显然@t1中的所有FName为“马云”的都会被更新成“1”,而FName为“马化腾”、“李彦宏”和“刘强东”的都无法匹配到。脚本写法如下:

...上面的定义和初始化脚本省略
update t1
 set t1.FSerial=t2.FSerial
from @t1 t1
inner join @t2 t2 on t1.FName=t2.FName
select * from @t1

执行的结果确实如此,参看下图:

多条匹配多表更新的隐藏问题

还是基于上面的例子,如果我们把要更新的对象倒转,使用@t1的数据来更新@t2表的数据,这时候问题就来了,在表@t1中,有多条叫做“马云”的记录,如果我们把@t1的FID基于FName相同的条件更新到@t2的FID,到底那一条叫做“马云”的记录对应的FID会被更新过去呢?

先上代码:

...上面的定义和初始化脚本省略
update t2
 set t2.FID=t1.FID
from @t2 t2
inner join @t1 t1 on t2.FName=t1.FName
select * from @t2

执行的结果可能是您未想到的:

通过上图您可以看出,当存在多条,正常排序的最后一条匹配记录值被更新过去了。

这或许至少就是SQL Server内部的逻辑,写多了就成了经验,知道就行了,内部的逻辑也不好深入探究。

希望对您有所帮助!

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言