Man*_*wat 4 sql-server triggers
好的,我认为问题不明确.在这里,我以其他方式重写这一点.
假设我创建了两个表,
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')
Run Code Online (Sandbox Code Playgroud)
现在我想要实现的是,一旦我更新的值c1在table1相应的数据table2就会自动改变.为此,我需要在table1和table2关系中创建约束并应用CASCADE UPDATE.
所以,稍后我在table1ie中应用一个新的SQL更新语句
Update table1 set c1=c1+'updated'
Run Code Online (Sandbox Code Playgroud)
然后数据table2也会改变,但是如果我想通过实现相同的功能INSTEAD OF UPDATE TRIGGER,那么我需要编写而不是更新触发器,在里面,我需要处理两个魔术表INSERTED和DELETED.
但重点是,在这种情况下,我只有一个列存在table1,我正在更新同一列,所以我怎么能映射插入和删除的行.如果我使用CASCADing,SQL Server也会做同样的事情.
因此,问题出现了SQL Server如何在表中的主键数据更改的情况下处理批量更新.
Mik*_*son 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
)
Run Code Online (Sandbox Code Playgroud)
添加一些数据:
insert into T1 values(1), (2)
insert into T2 values(1, 1), (2, 1), (3, 2)
Run Code Online (Sandbox Code Playgroud)
更新主键T1:
update T1
set T1.T1ID = 3
where T1.T1ID = 1
Run Code Online (Sandbox Code Playgroud)
更新的查询计划如下所示:

该计划有两个Clustered Index Update步骤,一个用于T1,一个用于T2.
更新1:
当多个主键值更新时,SQL Server如何跟踪要更新的行?
update T1
set T1.T1ID = T1.T1ID + 100
Run Code Online (Sandbox Code Playgroud)

顶部分支(更新)中的Eager SpoolT1将旧T1ID计算和新计算保存T1ID (Expr1013)到下部分支(更新T2)使用的临时表中.在下面的分支哈希匹配与加盟表假脱机T2的老T1ID.从哈希匹配到的更新输出T2是T2ID从的聚集索引扫描T2和新的计算T1ID (Expr1013)从表假脱机.
更新2:
如果你需要替换cascade updatea,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)
);
Run Code Online (Sandbox Code Playgroud)
触发器可能看起来像这样.
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
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4960 次 |
| 最近记录: |