SQL SERVER Update from 使用陷阱
2017-01-03 14:45
323 查看
update A set from A left join B on
此方法常用来使用根据一个表更新另一个表的数据,来进行数据同步更新。若是A表行与B表行为一对一的对应关系,更新不存在问题,若是A表行与B表行对应关系为一对多的时候,需注意A表更新的列并非B表的累计值,而是第一个数值。
首先建立两个表 A,B 对A表建立触发器查看更新信息
执行结果
此执行结果理论上 value 应为3 ,实际执行 value 结果为1
对表数据进行初始化B
此方式实际执行 value 结果为2
此方法常用来使用根据一个表更新另一个表的数据,来进行数据同步更新。若是A表行与B表行为一对一的对应关系,更新不存在问题,若是A表行与B表行对应关系为一对多的时候,需注意A表更新的列并非B表的累计值,而是第一个数值。
首先建立两个表 A,B 对A表建立触发器查看更新信息
CREATE TABLE yshA ( keyA VARCHAR(10), value INT ) CREATE TABLE yshB ( keyB VARCHAR(10), valueB INT ) SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TRIGGER trg_YSHA_Up ON YSHA AFTER UPDATE AS BEGIN SET NOCOUNT ON; DECLARE @now VARCHAR(60) SET @now=convert(varchar,GETDATE()) SELECT *,'i',@now FROM inserted SELECT *,'d',@now FROM deleted END GO
1、对数据进行更新
对表数据进行初始化AINSERT INTO yshA VALUES (1,0) INSERT INTO yshB VALUES (1,1) INSERT INTO yshB VALUES (1,2) SELECT * FROM yshA A LEFT JOIN yshB B ON keyA=keyB
执行结果
UPDATE A SET value = value + valueB FROM yshA A LEFT JOIN yshB B ON keyA=keyB SELECT * FROM yshA
此执行结果理论上 value 应为3 ,实际执行 value 结果为1
对表数据进行初始化B
DELETE FROM yshA
DELETE FROM yshB
INSERT INTO yshA VALUES (1,0)
INSERT INTO yshB VALUES (1,2)
INSERT INTO yshB VALUES (1,1)
UPDATE A SET value = value + valueB FROM yshA A LEFT JOIN yshB B ON keyA=keyB SELECT * FROM yshA
此方式实际执行 value 结果为2
2、 原因分析
理论上以上两种更新的结果应为一致,同样的数据 方法B更新的结果与 方法A更新的结果不一致。针对此问题进行分析,首先进行执行计划分析,查看其它的正常,但是left join 之后多了一步执行操作 Top 开销 因此可以解析为什么两次更新的结果不一致,因为只根据首条关联进行更新。相关文章推荐
- SQL中的三值逻辑
- SQL Server 作业批量停止
- 结束SQL阻塞的进程
- 动态生成SQL Server视图作业
- Seafile Server本地权限提升漏洞(CVE-2014-5443)
- 从USB安装Ubuntu Server 10.04.3 图文详解
- SQL Server 语句操纵数据库
- 将Windows Server 2016 打造成好用的办公系统
- SQL(结构化查询语句)
- oracle sql日期比较
- 使用zabbix监控Nginx活动状态--Part1
- MaxScale Binlog Server实践
- 高效访问Internet-启用ISA Server的缓存
- linux快速部署mysql服务器
- 10 件在 PHP 7 中不要做的事情
- windows server域用户提升到本地更高权限组中的方法
- 使用SQL Server连接服务器访问DB2 Server