首页 > 代码库 > 曲演杂坛--Update的小测试

曲演杂坛--Update的小测试


今天偶然想起一个UPDATE相关的小问题,正常情况下,如果我们将UPDATE改写成与之对应的SELECT语句,其SELECT查询结果应与UPDATE的目标表存在一对一的关系,例如:

对于UPDATE语句:

UPDATE TB1 SET C2=TB2.C2 FROM TB1 INNER JOIN TB2 ON TB1.C1=TB2.C1

假设TB1中C1为主键,那么改写成对应的SELECT SQL

SELECT TB1.C1,TB1.C2 AS C2_OLD,TB2.C2 AS C2_NEWFROM TB1 INNER JOIN TB2 ON TB1.C1=TB2.C1

以上查询结果应该也可以以C1为主键,即C1在此查询结果中是唯一的。

问题出现了,如果查询结果中C1不唯一,那么更新后的结果会是什么呢?

让我们来测试下,准备测试数据:

CREATE TABLE TB001(    C1 INT,    C2 INT);GOCREATE TABLE TB002(    C1 INT,    C2 INT);DELETE FROM TB001DELETE FROM TB002INSERT INTO TB001(C1,C2)SELECT 1,1UNION ALLSELECT 2,1GOINSERT INTO TB002(C1,C2)SELECT 1,3UNION ALLSELECT 1,2UNION ALLSELECT 2,4GOSELECT * FROM TB001SELECT * FROM TB002GOSELECT *FROM TB001 T1 INNER JOIN TB002 T2ON T1.C1=T2.C1

查询结果中C1的记录并不唯一,如果我们对此更新,结果会是什么呢?

UPDATE方式1

--第一种更新UPDATE TB001SET C2=T1.C2*T2.C2FROM TB001 T1 INNER JOIN TB002 T2ON T1.C1=T2.C1--查看执行结果SELECT * FROM TB001

UPDATE方式2

--第二种更新UPDATE TB001SET C2=TB001.C1*T2.C2FROM TB002 T2WHERE TB001.C1=T2.C1--查看执行结果SELECT * FROM TB001

UPDATE方式3

--第三种更新WITH TMP AS(    SELECT T1.C1,T1.C2,T1.C2*T2.C2 AS NewC2    FROM TB001 T1     INNER JOIN TB002 T2    ON T1.C1=T2.C1)UPDATE TMPSET C2=NewC2--查看执行结果SELECT * FROM TB001

通过比较,不难看出,对于第一种和第三种方式,TB001中的C1=1的记录只被更新1次,而对于第二种方式来说,该记录被更新2次。

 

---====================================================================

对于上面的例子,无论那种方式,更新结果都可能不是我们预期的结果,因此我们避免此类操作(尤其是生产环境)。

尽管这些测试没有太多意义,但聊胜于无,供各位看官一看。

BTW:对于三种UPDATE写法,个人偏好第三种,因为可以很容易滴查看SELECT结果集,从而对更新后的结果有一个预期了解,以检查是否满足需求。

--====================================================================

很多人是来看妹子的,我懂你们的。。。

重口难调,你们将就下

 

曲演杂坛--Update的小测试