曲演杂坛--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),也没细细考究过为什么要这么写,只是隐约认为这样写没有啥问题,那今天就深究下吧! 首先准备测 ...
随机推荐
- Intellij IDEA使用Maven搭建spark开发环境(scala)
如何一步一步地在Intellij IDEA使用Maven搭建spark开发环境,并基于scala编写简单的spark中wordcount实例. 1.准备工作 首先需要在你电脑上安装jdk和scala以 ...
- Dungeon Game (GRAPH - DP)
QUESTION The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a ...
- K.O. -------- Eclipse中Maven的报错处理
----------------------siwuxie095 K.O. -------- Eclipse 中 Maven 的报错处理 ...
- 四种强制类型转换的总结(const_cast、static_cast、dynamic_cast、reinterpreter_cast)
四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast) 转载 2011年10月03日 23:59:05 标签: stru ...
- .NET资源文件实现多语言切换
1.创建对应的资源文件 lang.en.resx 英文 lang.resx 中文,默认 lang.zh-tw.resx 繁体 首先说明,这三个文件前面部分名称需要一样,只是 点 后面的语言代号 ...
- css简单分页
html代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <ti ...
- python使用input()来接受字符串时一直报错“xxx is not defined”
报错信息: “Please input your guess: gussTraceback (most recent call last): File "coinGuessGame.py& ...
- WinScp获取一个文件
CD /d C:\Program Files (x86)\WinSCPWinSCP.exe /console /command "option batch continue" &q ...
- [Jmeter]Xpath获取元素某个属性的值,以及获取最后一个元素某个属性的值
XPath获取元素某个属性的值 XPath query: clients/attribute::total XPath获取最后一个元素某个属性的值 XPath query: /clients/c ...
- 解决Axure发布分享预览的3个方法
公司的同事制作的一个产品原型,要发给我,我当时正在客户这里,电脑上并没有Axure,客户又催得急,感到一阵无奈.这次回来之后,经过一番摸索,发现还是有办法的.这里给大家分享一下Axure发布分享预览的 ...