曲演杂坛--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_NEW
FROM TB1
INNER JOIN TB2
ON TB1.C1=TB2.C1
以上查询结果应该也可以以C1为主键,即C1在此查询结果中是唯一的。
问题出现了,如果查询结果中C1不唯一,那么更新后的结果会是什么呢?
让我们来测试下,准备测试数据:
CREATE TABLE TB001
(
C1 INT,
C2 INT
);
GO
CREATE TABLE TB002
(
C1 INT,
C2 INT
); DELETE FROM TB001
DELETE FROM TB002 INSERT INTO TB001(C1,C2)
SELECT 1,1
UNION ALL
SELECT 2,1 GO
INSERT INTO TB002(C1,C2)
SELECT 1,3
UNION ALL
SELECT 1,2
UNION ALL
SELECT 2,4 GO
SELECT * FROM TB001
SELECT * FROM TB002
GO
SELECT *
FROM TB001 T1
INNER JOIN TB002 T2
ON T1.C1=T2.C1

查询结果中C1的记录并不唯一,如果我们对此更新,结果会是什么呢?
UPDATE方式1
--第一种更新
UPDATE TB001
SET C2=T1.C2*T2.C2
FROM TB001 T1
INNER JOIN TB002 T2
ON T1.C1=T2.C1 --查看执行结果
SELECT * FROM TB001

UPDATE方式2
--第二种更新
UPDATE TB001
SET C2=TB001.C1*T2.C2
FROM TB002 T2
WHERE 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 TMP
SET C2=NewC2
--查看执行结果
SELECT * FROM TB001

通过比较,不难看出,对于第一种和第三种方式,TB001中的C1=1的记录只被更新1次,而对于第二种方式来说,该记录被更新2次。
---====================================================================
对于上面的例子,无论那种方式,更新结果都可能不是我们预期的结果,因此我们避免此类操作(尤其是生产环境)。
尽管这些测试没有太多意义,但聊胜于无,供各位看官一看。
BTW:对于三种UPDATE写法,个人偏好第三种,因为可以很容易滴查看SELECT结果集,从而对更新后的结果有一个预期了解,以检查是否满足需求。
--====================================================================
很多人是来看妹子的,我懂你们的。。。
重口难调,你们将就下


曲演杂坛--Update的小测试的更多相关文章
- 曲演杂坛--一条DELETE引发的思考
原文:曲演杂坛--一条DELETE引发的思考 场景介绍: 我们有一张表,专门用来生成自增ID供业务使用,表结构如下: CREATE TABLE TB001 ( ID ,) PRIMARY KEY, D ...
- 曲演杂坛--为什么SELECT语句会被其他SELECT阻塞?
很多刚入门的DBA在捕获阻塞得时候,会问这么一个问题“为什么这个SELECT语句被那个SELECT语句阻塞了,难道不是共享锁么?” 让我们来做个小测试,首先准备一些测试数据: --========== ...
- 曲演杂坛--使用TRY CATCH应该注意的一个小细节
群里一个朋友遇到一个TRY CATCH的小问题,测试后发现是自己从来没有考虑的情况,写篇blog加深下印象 --============================================ ...
- 曲演杂坛--使用CTE时踩的小坑:No Join Predicate
在一次系统优化中,意外发现一个比较“坑”的SQL,拿出来供大家分享. 生成演示数据: --====================================== --检查测试表是否存在 IF(O ...
- 曲演杂坛--使用ALTER TABLE修改字段类型的吐血教训
--===================================================================== 事件起因:开发发现有表插入数据失败,查看后发现INT类型 ...
- 曲演杂坛--蛋疼的ROW_NUMBER函数
使用ROW_NUMBER来分页几乎是家喻户晓的东东了,而且这东西简单易用,简直就是程序员居家必备之杀器,然而ROW_NUMBER也不是一招吃遍天下鲜的无敌BUG般存在,最近就遇到几个小问题,拿出来供大 ...
- 曲演杂坛--当ROW_NUMBER遇到TOP
值班期间研发同事打来电话,说应用有超时,上服务器上检查发现有SQL大批量地执行,该SQL消耗IO资源较多,导致服务器存在IO瓶颈,细看SQL,发现自己都被整蒙了,不知道这SQL是要干啥,处理完问题赶紧 ...
- 曲演杂坛--特殊字符/生僻字与varchar
对于中文版的SQL SERVER,默认安装后使用的默认排序规则为Chinese_PRC_CI_AS,在此排序规则下,使用varchar类型来可以“正常存取”存放中文字符以及一些东南亚国家的字符,同时v ...
- 曲演杂坛--EXISTS语句
通常在我写EXISTS语句时,我会写成IF EXISTS(SELECT TOP(1) 1 FROM XXX),也没细细考究过为什么要这么写,只是隐约认为这样写没有啥问题,那今天就深究下吧! 首先准备测 ...
随机推荐
- mogodb查询
Find: {$and: [ {"MethodName":"CommLogin"} ,{"CreateTime":{$gte:"2 ...
- vs2015安装出问题
win7系统需要更新serverpage1包,更新完就ok了,ie不用升级到ie10
- python之字符串【str】
#Auther Bob#--*--conding:utf-8 --*-- #定义一个str的对象,有下面两种方法name = 'Bob abc'job = str('it')print(type(na ...
- day7:vcp考试
Q121. An ESXi 6.x host in the vCenter Server inventory has disconnected due to an All Paths Down (AP ...
- VS代码页到设计页传值
代码页 public string titleZRclass = ""; 根据条件设置其值 设计页 <%=titleZRclass %>
- centos7下源码安装mysql5.7.16
一.下载源码包下载mysql源码包 http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.16.tar.gz 二.安装约定: 用户名:mysql 安装目录 ...
- [z]Windows 下基于 Eclipse 的可视化远程 Linux C/C++ 开发环境搭建
http://blog.csdn.net/lostaway/article/details/8086056 1.简介 Windows 下远程 Linux 开发工具,比较著名的就是 WinGDB 和 M ...
- 嵌入式的SQL程序设计
嵌入式的SQL程序设计 sql语句大全之嵌入式SQL 2017-01-18 16:00 来源:未知 嵌入式SQL 为了更好的理解嵌入式SQL,本节利用一个具体例子来说明.嵌入式SQL允许程序连接数 ...
- json.dumps错误:'utf8' codec can't decode byte解决方案-乾颐堂
一次在使用json.dumps()过程中,出现错误提示: ERROR:"UnicodeDecodeError: 'utf8' codec can't decode byte 0xe1 in ...
- VisulaVM 性能:分析 JVM 性能的免费工具
VisualVM是一个集成多个JDK命令行工具的可视化工具.可以作为Java应用程序性能分析和运行监控的工具.开发人员可以利用它来监控.分 析线程信息,浏览内存堆数据.系统管理员可以利用它来监测.控制 ...