如何在SQL Server内部级联更新/删除?

时间:2013-02-24 17:18:37

标签: sql-server triggers

好的,我相信问题不明确。在这里,我以其他方式重写了这一点。

假设我创建了两个表,

  • table1(c1 int PRIMARY KEY)

  • table2(table1c11 int)

table1table2之间存在关系 即table1.c1=table2.table1c11

并且,我在table1table2

中执行以下语句
insert into table1(c1)
values('a'),('b'),('c'),('d'),('e')

insert into table2(table1c11)
values('a'),('a'),('b'),('d')

现在我想要实现的是,一旦我在c1中更新table1的值,table2中的相应数据就会自动更改。为此,我需要在table1table2关系中创建约束并应用CASCADE UPDATE

因此,稍后我在table1中应用新的SQL更新语句,即

Update table1 set c1=c1+'updated'

然后table2中的数据也会发生变化,但是如果我想通过INSTEAD OF UPDATE TRIGGER实现相同的功能,那么我需要编写而不是更新触发器,在内部,我需要使用两个魔术表INSERTEDDELETED来处理它。

但重点是,在这种情况下,table1中只有一列存在并且我正在更新同一列,因此我如何映射插入和删除的行。如果我使用CASCADing,SQL Server也会做同样的事情。

因此,问题出现了SQL Server如何在表中主键数据发生变化的情况下处理批量更新。

1 个答案:

答案 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

更新的查询计划如下所示:

query plan for update with on update cascade

该计划有两个Clustered Index Update步骤,一个用于T1,另一个用于T2

更新1:

如果更新了多个主键值,SQL Server如何跟踪要更新的行?

update T1
set T1.T1ID = T1.T1ID + 100

query plan for update with on update cascade more than one row

顶部分支中的Eager SpoolT1的更新)将旧T1ID和新计算的T1ID (Expr1013)保存到下级分支使用的临时表中(T2的更新)。下部分支中的哈希匹配将旧表T2上的表假脱机加上T1ID。哈希匹配到T2更新的输出来自T2ID的聚簇索引扫描{1}}以及表假脱机中新计算的T2

更新2:

如果您需要将T1ID (Expr1013)替换为cascade update,则需要有一种方法可以加入触发器中的instead of triggerinserted表。这可以通过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)
);

SQL Fiddle