Sql server 级联更新/删除在SQL Server内部如何工作?

Sql server 级联更新/删除在SQL Server内部如何工作?,sql-server,triggers,Sql Server,Triggers,好吧,我想问题还不清楚。这里我用另一种方式重写了这个 假设我创建两个表 表1(c1 int主键) table2(table1c11 int) table1和table2 i、 e.table1.c1=table2.table1c11 并且,我在table1和table2 insert into table1(c1) values('a'),('b'),('c'),('d'),('e') insert into table2(table1c11) values('a'),('a'),('b'

好吧,我想问题还不清楚。这里我用另一种方式重写了这个

假设我创建两个表

  • 表1(c1 int主键)

  • table2(table1c11 int)

table1
table2
i、 e.
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')
现在我想实现的是,一旦我更新了
table1
c1
的值,
table2
中的相应数据就会自动更改。为此,我需要在
表1
表2
关系中创建约束,并应用
级联更新

因此,稍后我将在
表1
中应用一个新的SQL update语句,即

Update table1 set c1=c1+'updated'
然后
表2中的数据也会发生变化,但是如果我想通过
而不是更新触发器来实现相同的功能,那么我需要编写代替更新触发器,在其中,我需要使用两个神奇的表
插入
删除
,来处理这个问题

但主要的一点是,在本例中,
表1中只有一列,我正在更新同一列,因此如何映射插入和删除的行。如果我使用级联,SQL Server也会做同样的事情

因此,问题出现了,如果表中的主键数据发生更改,SQL Server如何处理批更新

因此,出现了一个问题,即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
更新的查询计划如下所示:

该计划有两个聚集索引更新步骤,一个用于
T1
,另一个用于
T2

更新1:

当更新多个主键值时,SQL Server如何跟踪要更新的行

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

顶部分支中的(更新
T1
)将旧的
T1ID
和新计算的
T1ID(Expr1013)
保存到一个临时表中,供下部分支使用(更新
T2
)。下面分支中的哈希匹配将表Spool与旧的
T1ID
上的
T2
连接起来。从散列匹配到更新
T2
的输出是
T2ID
聚集索引扫描的
T2
,以及从表假脱机计算的新
T1ID(Expr1013)

更新2:

如果需要将
级联更新
替换为
而不是触发器
,则需要在触发器中加入插入的
和删除的
表。这可以通过
T1
中的代理键完成

表:

create table T1
(
  T1ID int primary key,
  ID int identity unique
);

create table T2
(
  T2ID int primary key, 
  T1ID int references T1(T1ID)
);
触发器可能是这样的

create trigger tr_T1 on T1 instead of update as

insert into T1(T1ID)
select T1ID
from inserted;

update T2
set T1ID = I.T1ID
from inserted as I
  inner join deleted as D
    on I.ID = D.ID
where D.T1ID = T2.T1ID;

delete from T1
where T1ID in (
              select T1ID
              from deleted
              );

是否允许您更改表的结构(我的意思是表2)?是的,我可以,但问题是,表2中有两列,我需要在您创建的下一个表中添加这些列。因此,我可以创建表3,但是表3应该引用表2而不是表1。您可以从查询计划中提取信息并向我建议触发器吗。这对我很有帮助。在update语句中,您只更新了一条记录,这很容易映射到插入/删除的魔法表中。我相信,如果您执行像updatet1 SET T1.T1ID=T1.T1ID+100这样的批处理更新,那么这将是一个非常好的示例,在那里我可以真正理解SQL Server内部级联背后的概念。提前感谢您的时间。@ManishRawat使用修改多行的update语句不会对查询计划造成太大的更改,请尝试并查看。您询问了SQL Server是如何进行更新的,这就是如何进行更新的。你也在问如何使用触发器进行级联更新吗?@ManishRawat-nope,没有。我认为在触发器中没有任何方法可以做到这一点,除非您可以在
T1
中添加某种代理键,您可以将其用作插入的
和删除的
之间的连接。它可以是具有唯一约束的
标识
列。标识列不必是主键<代码>创建表T1(T1ID int主键,ID int标识唯一)
@ManishRawat是的,SQL计划告诉您SQL Server在内部是如何做到这一点的,我认为这就是这个问题的内容。在触发器中,如果不修改表,就无法执行此操作。你有三种方法来解决你的处境。1删除
T2
中没有有效FK到
T1
的所有行。2将所有必要的行添加到
T1
,以便
T2
中的所有行都具有有效的FK。3允许在
T2
中的FK中使用空值,并将
T2
中的FK更新为空,以用于所有没有有效FK的行。