MS SQL Server 中如何实现一对多外键的级联更新

SQL外键实战:从数据一致性到生产级性能优化 外键(Foreign Key)是关系型数据库保障数据一致性的核心机制,其本质是数据库引擎在事务层实现的双向、原子化引用约束。它通过主键索引探查、行级锁协同与元数据缓存,在插入、更新、删除时实时拦截非法关联,彻底消除应用层校验的时间窗口漏洞。相比代码模拟,外键提供强一致性保障与声明式维护能力,技术价值体现在故障防御(如防止孤儿订单)、运维提效(自动级联/置空)和模型可演进性上。典型应用场景包括电商订单与用户/商品的关联建模、多对多桥接表设计、历史快照保留等。本文聚焦真实生产环境中的外键落地——覆盖MySQL/ 阅读详情
我最近在做项目时发现,我有一个表A、表B,在表B中三处引用了A的主键。我希望在表A主键更新时能够自动更新。但是MS SQL Server不用在一个表的外键约束只能使用一次级联操作(ON UPDATE CASCADE),这样就导致不能修改表A的主键,修改就报错(因为外键约束)。看了MS SQL SERVER的说明,可以用INSTEAD OF UPDATE触发器,但是找了半天资料,都是基于视图的,仿照写了一个,整个表A的数据都不能修改了,也不报错。谁能告诉我该怎么办?

----------------------------------------------------------------------

B表的三个字段只能有一个可以由系统自动级联更新或级联删除,其他两个字段可以建外键,但不能级联更新或删除,只能自己写触发器来处理。


--------------------------------------------------------

这种情况下,必须取消B表的另外二个非级联外键的'对INSERT和UPDATE强制关系',否则A表主键和B表的非级联外键都无法修改.
之后,为A表创建UPDATE触发器,修改主键时更新B表非级联外键的值,并且还要创建DELETE触发器,当主键被删除时,将B表的非级联更新外键值设为NULL,否则无法删除主键.
建议楼主为A表添加IDENTITY标识列,并为该列设置UNIQUE约束,使该ID列能唯一定位行,用于触发器中.
请楼主参考以下代码.首先建立了二个表,testtable1是主键表,主键列为pid,testtable2为外键表,外键为ChildID(级联),fidx(禁止INSERT和UPDATE约束),fidy(禁止INSERT和UPDATE约束),为testtable1建立了UPDATE和DELETE触发器.请楼主测试一下.

--------------------------------------------------------

if object_id('testtable2') is not null
drop table testtable2
if object_id('testtable1') is not null
drop table testtable1
GO
----创建主键表,主键列为pid,IDENTITY列为id,并为id设置UNIQUE约束,保证id唯一
CREATE TABLE testTable1(id int IDENTITY(1,1) NOT NULL ,pid varchar(10) NOT NULL) ON [PRIMARY]
GO
ALTER TABLE testTable1 ADD 
CONSTRAINT PK_testTable1 PRIMARY KEY  CLUSTERED (pid) ON [PRIMARY] ,
CONSTRAINT IX_testTable1 UNIQUE  NONCLUSTERED (id)  ON [PRIMARY] 
GO
----创建外键表,ChildID为级联更新外键,fidx和fidy为非级联外键
CREATE TABLE testTable2(ChildID varchar(10),fidx varchar(10),fidy varchar(10)) ON [PRIMARY]
GO
ALTER TABLE testTable2 ADD 
CONSTRAINT FK_testTable2_testTable1 FOREIGN KEY (ChildID) REFERENCES testTable1(pid) ON DELETE CASCADE ON UPDATE CASCADE NOT FOR REPLICATION ,
CONSTRAINT FK_testTable2_testTable11 FOREIGN KEY (fidx) REFERENCES testTable1(pid) NOT FOR REPLICATION ,
CONSTRAINT FK_testTable2_testTable12 FOREIGN KEY (fidy) REFERENCES testTable1(pid) NOT FOR REPLICATION 
----禁止非级联外键的'强制INSERT和UPDATE约束'
alter table testTable2 nocheck constraint FK_testTable2_testTable11
alter table testTable2 nocheck constraint FK_testTable2_testTable12
GO
----插入测试数据
insert into testtable1(pid) values('1')
insert into testtable1(pid) values('2')
insert into testtable1(pid) values('3')
insert into testtable1(pid) values('4')
insert into testtable1(pid) values('5')
insert into testtable1(pid) values('6')
insert into testtable2(ChildID,fidx,fidy) values('1','6','6')
insert into testtable2(ChildID,fidx,fidy) values('2','5','5')
insert into testtable2(ChildID,fidx,fidy) values('3','4','4')
insert into testtable2(ChildID,fidx,fidy) values('4','3','3')
insert into testtable2(ChildID,fidx,fidy) values('5','2','2')
insert into testtable2(ChildID,fidx,fidy) values('5','1','1')
GO
----创建UPDATE触发器
CREATE TRIGGER tri_update_tab1 on testtable1
for update
as
if update(pid)
begin
update a set fidx = i.pid from testtable2 a,inserted i,deleted d where a.fidx = d.pid and i.id = d.id
update a set fidy = i.pid from testtable2 a,inserted i,deleted d where a.fidy = d.pid and i.id = d.id
/*----如果楼主的表中没有id列,请使用以下代码,使inserted表和deleted表能行对应
if object_id('tempdb..#inserted') is not null
drop table #inserted
if object_id('tempdb..#deleted') is not null
drop table #deleted
select ids = identity(int,1,1),* into #inserted from inserted
select ids = identity(int,1,1),* into #deleted from deleted
update a set x = i.pid from table2 a,#inserted i,#deleted d where a.x = d.pid and i.ids = d.ids
update a set y = i.pid from table2 a,#inserted i,#deleted d where a.y = d.pid and i.ids = d.ids
drop table #inserted,#deleted
*/
end
GO
----创建DELETE触发器,将外键值设为NULL
CREATE TRIGGER tri_delete_tab1 on testtable1
for delete
as
update a set fidx = NULL from testtable2 a,deleted d where a.fidx = d.pid
update a set fidy = NULL from testtable2 a,deleted d where a.fidy = d.pid
GO

--------------------------------------------------------

请在查询分析器中进行测试:
----测试UPDATE触发器(请使用right(rtrim(pid),1)恢复为原来的pid值)
update a set pid = 'T' + pid from testtable1 a      
select 'Afterupdate',* from testtable2
----测试DELETE触发器
delete testtable1 where pid in('T1','T2')
select 'Afterdelete',* from testtable2
----恢复pid原值
update a set pid = right(rtrim(pid),1) from testtable1 a
select * from testtable2

--drop table testtable2,testtable1 
 
使用SQL Server触发器实现数据表的级联更新.pdf 立即下载

相关推荐

基于FPGA与红外成像的眼动追踪系统设计与实现(教学向)

本文详细介绍了基于FPGA与红外成像的眼动追踪系统设计与实现。通过红外摄像头采集图像,利用FPGA进行实时图像处理和红外瞳孔追踪,结合Verilog编程实现多目标检测与瞳孔定位。该系统适用于嵌入式视觉教学,展示了硬件搭建、算法优化及实时显示的完整流程。

g5h6i7j的博客 823

Access中用SQL语句将其中一个表的列更新到另一个表的对应列

有两个表: 表1 ... Name Tel ... 表2 ... Name Tel ... 现要将根据两个表的Name字段进行匹配来更新表1的Tel字段,Access SQL语名写法如下: Update 表1,表2 Set 表1.Tel = 表2.Tel Where 表1.Name = 表2.Name

dibowei2069的专栏 2225

演化计算(蚁群算法、粒子群算法、遗传算法、演化规则......)

演化算法1.概念2.解决的问题 1.概念 传统算法(如梯度下降法、爬山法)根据导数的性质决定迭代的方向;而演化计算是一组解在一起协同作用产生一个最优解。 2.解决的问题 预测优化:演化计算(蚁群算法、粒子群算法、遗传算法等) 解的聚散、多样性:通过多次聚散,尽快得出最优解(某个解不合要求,要能够发散出去) ...

dear_jing的博客 4162

mssql语句cascade级联delete/update

-删除子表员工表(employee)下的属于部门2的所有数据,父表部门表(department)的部门2不会删除。references department(id) --父表主键。--作用:如果父表中的记录被删除,则子表中对应该记录的自动被删除/更新。--删除(更改)部门表的部门3,则员工表属于部门3的数据也会被删除。(1,'员工1',1),(2,'员工2',1),(3,'员工3',2),(4,'员工4',2),(5,'员工4',3)(1,'部门1'),(2,'部门2'),

weixin_44519072的博客 981

从‘静态拍照’到‘动态录像’:用Malmquist指数讲好你的效率变化故事(附Stata/R代码)

本文深入探讨了如何利用Malmquist指数构建动态效率分析框架,从静态数据到动态叙事的转变。通过分解技术效率变化(EC)和技术进步(TC),结合Stata/R代码实现四种动态可视化方法,帮助研究者更直观地展示效率变化的动态特征。文章还提供了诊断性叙事结构和比较叙事技巧,助力决策者理解效率提升的来源与趋势。

weixin_32678995的博客 603

解决mamba_ssm库安装难题:两种高效方法详解

本文详细解析了mamba_ssm库安装失败的常见原因,并提供了两种高效的解决方案。针对其依赖C++/CUDA扩展编译的特性,文章手把手指导用户通过GitHub克隆源码编译安装,或寻找匹配的预编译Wheel文件直接安装,帮助开发者彻底解决环境配置难题,顺利部署Mamba模型。

weixin_29056865的博客 553

sqlserver 级联删除、级联更新

增加外键约束时,设置级联更新、级联删除:[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ][ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] create table Employees ( EmpId int identity(1...

weixin_30405421的博客 392

【机器视觉】基于深度学习的托盘PCB识别与计数(有无、正反)

工业机器视觉是指在制造业和工业环境中使用计算机视觉技术来执行检测、测量、识别和控制任务。它结合了硬件(如相机、镜头、光源)与软件(图像处理算法)来自动完成传统上需要人工视觉的任务,从而提高生产效率、产品质量以及工作安全性。工业机器视觉系统通常具有高精度、高速度和高可靠性,能够适应恶劣的工作环境。

专注上位机开发、机器视觉、机器学习、嵌入式软硬件开发 1万+

SQL Server 可视化设置主键和外键

直接右键选中 -> 设置主键设置组合主键:ctrl选中多个元素 -> 右键 -> 设置主键。

2301_76979886的博客 2474

一分钟理解 “熔断“, “限流“ 与 “降级“

熔断,本质是一种“故障隔离”机制,用于当某个依赖服务出现持续故障(如响应超时、错误率飙升)时,暂时切断对该服务的调用,避免故障扩散到整个系统,防止“雪崩效应”;待依赖服务恢复正常后,再逐步恢复调用。其核心逻辑参考了现实中的“电路保险丝”——电路过载时,保险丝熔断,切断电路,保护电器不被烧毁;故障排除后,更换保险丝,电路恢复正常。闭合状态(Closed):正常状态,请求可以正常调用依赖服务,同时监控调用的错误率、超时率等指标。打开状态(Open)

h a 6 6 6 c k 为 你解决复杂难题! 1452

【全球人口数据集】全球人口密度数据集GPWv4

全球人口密度数据集GPWv4

WW、forever的博客 1002

sql 外键约束

sql server中建立外键约束有3中方式:  1.Enterprise Manager中,Tables,Design Table,设置Table的properties,   可以建立constraint, reference key;  2.Enterprise Manager中,Diagrams, new Diagrams,建立两个表的关系。  3.直接用transact sql语...

weixin_30667301的博客 462

yolov5运行detect.py之后卡住了?没后续,没结果,没报错,怎么办?如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1104

sql server 外键 更新(删除)规则

<br /><br />以前用数据库,一般都建表关系,但是这些关系建好了往往没有用到.<br /><br />这次写一个项目,涉及到多表的外键约束和级联删除的问题,才研究了一下.<br /><br />用的vs2005里面自带的SqlExpress,在VS里面作数据库,感觉不是很方便(废话,都方便了,那sqlserver2005 dev 卖给谁去!)<br /><br />我建了表,然后建了关系,设定了外键约束.<br /><br />然后就以为万事大吉了,去写代码,画界面去了.<br /><br />把代

明 天 3845

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

mysql外键更新规则_sql server 外键 更新(删除)规则

以前用数据库,一般都建表关系,但是这些关系建好了往往没有用到.这次写一个项目,涉及到多表的外键约束和级联删除的问题,才研究了一下.用的vs2005里面自带的SqlExpress,在VS里面作数据库,感觉不是很方便(废话,都方便了,那sqlserver2005 dev 卖给谁去!)我建了表,然后建了关系,设定了外键约束.然后就以为万事大吉了,去写代码,画界面去了.把代码和界面搞定后,一试验删除,删除...

weixin_31004409的博客 995

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

mysql外键更新规则_SQL Server 外键 更新(删除)规则

此文主要向大家讲述的是SQL Server 外键的更新(删除)的实际操作规则,以前用数据库德 时候一般都建表关系,但是把这些关系建好了之后往往都用不上,这次写一个项目,涉及到多表的SQL Server 外键约束和级联删除的问题,才研究了一下.用的vs2005里面自带的SqlExpress,在VS里面作数据库,感觉不是很方便(废话,都方便了,那sqlserver2005 dev 卖给谁去!)我建了表...

weixin_34929072的博客 940

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

SQLServer:查询所有外键关联表信息

--从左到右分别是: 外键约束名,子表名,外键列名,父表名 --use demodtcms--外键信息select fk.name fkname , ftable.name ftablename, cn.name fkcol, rtable.name ftablename,ObjectProperty(fk.id,'CnstIsUpdateCascade') updatCase,ObjectP...

weixin_30367873的博客 564

数据库一对多关系设计实战:从外键原理到索引优化

一对多关系是关系型数据库最基础也最易误用的核心范式,其本质是业务归属规则在数据层的映射。理解它需穿透SQL语法,深入B+树索引结构、事务锁机制与范式约束原理——外键为何必须置于子表?NULL值如何让索引失效?复合索引为何要遵循最左前缀?这些技术决策直接决定查询性能、数据一致性和系统可扩展性。在电商、金融等高并发场景中,合理设计一对多结构能规避全表扫描、级联删除风险与主从延迟飙升等问题。本文基于MySQL 8.0、PostgreSQL 15和SQL Server 2022真实生产实践,覆盖外键约束、索引优化、

weixin_30781775的博客 365

SQL外键实战指南:保障引用完整性与线上热修复

外键(Foreign Key)是关系型数据库实现引用完整性(Referential Integrity)的核心机制,其本质是在事务提交前由存储引擎强制校验子表记录是否指向真实存在的父表主键或唯一键。相比应用层模拟校验,原生外键可彻底规避竞态条件,确保高并发下的数据一致性。它通过隐式或显式索引支撑高效检查,在MySQL InnoDB、PostgreSQL等主流引擎中提供RESTRICT、CASCADE、SET NULL等行为策略,适用于订单与用户、分类父子关系、分片映射等典型场景。本文聚焦真实生产环境中的建表

weixin_33827590的博客 518

SQLServer 查询所有外键关联表信息

有时候需要清除一些数据,但是总会有一些外键关联多加阻拦,下面是一些外键关联查询,方便更快捷有效的查询到需要处理的外键信息。 一、外键信息 查询列从左到右分别是: 外键约束名,子表名,外键列名,父表名 --外键信息 select fk.name fkname , ftable.name ftablename, cn.name fkcol, rtable.name ftablename,ObjectProperty(fk.id,'CnstIsUpdateCascade') updatCase,ObjectPr

weixin_43343835的博客 1941

SQL Server 外键 更新(删除)规则

转载:http://database.51cto.com/art/201006/206351.htm 此文主要向大家讲述的是SQL Server 外键的更新(删除)的实际操作规则,以前用数据库德 时候一般都建表关系,但是把这些关系建好了之后往往都用不上,这次写一个项目,涉及到多表的SQL Server 外键约束和级联删除的问题,才研究了一下. 用的vs2005里面自带的SqlExpres...

weixin_30343157的博客 139
上一篇: .Net中的反射使用入门
下一篇: Title:查询表主键外键信息的SQL
cuoguo1111
博客等级 码龄20年 21粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值