好的,我相信问题不明确。在这里,我以其他方式重写了这一点。
假设我创建了两个表,
table1(c1 int PRIMARY KEY)
table2(table1c11 int)
table1
和table2
之间存在关系
即table1.c1=table2.table1c11
并且,我在table1
和table2
insert into table1(c1)
values('a'),('b'),('c'),('d'),('e')
insert into table2(table1c11)
values('a'),('a'),('b'),('d')
现在我想要实现的是,一旦我在c1
中更新table1
的值,table2
中的相应数据就会自动更改。为此,我需要在table1
和table2
关系中创建约束并应用CASCADE UPDATE
。
因此,稍后我在table1
中应用新的SQL更新语句,即
Update table1 set c1=c1+'updated'
然后table2
中的数据也会发生变化,但是如果我想通过INSTEAD OF UPDATE TRIGGER
实现相同的功能,那么我需要编写而不是更新触发器,在内部,我需要使用两个魔术表INSERTED
和DELETED
来处理它。
但重点是,在这种情况下,table1
中只有一列存在并且我正在更新同一列,因此我如何映射插入和删除的行。如果我使用CASCADing,SQL Server也会做同样的事情。
因此,问题出现了SQL Server如何在表中主键数据发生变化的情况下处理批量更新。
答案 0 :(得分:12)
因此,问题出现了SQL Server如何处理批量更新 表中的主键数据发生了变化。
SQL Server为更新两个表的update语句构建查询计划。
创建表格:
create table T1
(
T1ID int primary key
);
create table T2
(
T2ID int primary key,
T1ID int references T1(T1ID) on update cascade
)
添加一些数据:
insert into T1 values(1), (2)
insert into T2 values(1, 1), (2, 1), (3, 2)
更新T1
的主键:
update T1
set T1.T1ID = 3
where T1.T1ID = 1
更新的查询计划如下所示:
该计划有两个Clustered Index Update步骤,一个用于T1
,另一个用于T2
。
更新1:
如果更新了多个主键值,SQL Server如何跟踪要更新的行?
update T1
set T1.T1ID = T1.T1ID + 100
顶部分支中的Eager Spool(T1
的更新)将旧T1ID
和新计算的T1ID (Expr1013)
保存到下级分支使用的临时表中(T2
的更新)。下部分支中的哈希匹配将旧表T2
上的表假脱机加上T1ID
。哈希匹配到T2
更新的输出来自T2ID
的聚簇索引扫描{1}}以及表假脱机中新计算的T2
。
更新2:
如果您需要将T1ID (Expr1013)
替换为cascade update
,则需要有一种方法可以加入触发器中的instead of trigger
和inserted
表。这可以通过deleted
中的代理键来完成。
表:
T1
触发器可能如下所示。
create table T1
(
T1ID int primary key,
ID int identity unique
);
create table T2
(
T2ID int primary key,
T1ID int references T1(T1ID)
);