关于触发器删除关联表数据的问题?

leejelen 2010-06-23 03:02:35
我有两个表。
表A : Aid Aname
表B : Bid Bname Aid
表C : Cid Cname Bid


表A和表B是一对多的关系,表B和表C也是一对多的关系。
问题是:当我删除表A的数据A1时,B中有对应的数据两条A1->B1,B2。那C中有对应的数据B1对应C1,C2;B2对应C3,C4,写触发器要如何把这些关联的数据都删除掉,能实现么,请高手赐教!
...全文
264 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
leejelen 2010-06-23
  • 打赏
  • 举报
回复
多谢大家的帮忙,已经解决了。分不够给。见谅见谅
nightmaple 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 leejelen 的回复:]
我有四个表。
表A : Aid Aname
表B : Bid Bname Aid
表C : Cid Cname Aid
表D : Did Dname Bid Cid

表A和表B是一对多的关系,表A和表C是一对多的关系,表B和表D也是一对多的关系。表C和表D也是一对多的关系。

现在的问题是,刚刚的已经可以实现从一级删除到三级,表C是通过表B来删除的。但是如果我是删除表C的数据时,……
[/Quote]

如果你在A上建删B的触发器,在B上建删C的触发器,没有建在A上删C的触发器
那么当你删了A上一条记录时,会自动删B表的相关记录,也会自动删C表相关的记录

那此记录多删了,自己检查触发器有没有建对
nightmaple 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 leejelen 的回复:]
DELETED 是代表什么啊?自带的函数么?代表当前需要操作删除的数据记录?
[/Quote]

触发器有两个表,inerted和deleted
deleted 是你删除的那条数据
inserted 是你新增的那条数据

如果你做update操作,则这两个表里都有数据,deleted中是你update之前的数据,inerted中是你update之后的数据。

wenwenaidami 2010-06-23
  • 打赏
  • 举报
回复
呵呵~~
leejelen 2010-06-23
  • 打赏
  • 举报
回复
我有四个表。
表A : Aid Aname
表B : Bid Bname Aid
表C : Cid Cname Aid
表D : Did Dname Bid Cid

表A和表B是一对多的关系,表A和表C是一对多的关系,表B和表D也是一对多的关系。表C和表D也是一对多的关系。

现在的问题是,刚刚的已经可以实现从一级删除到三级,表C是通过表B来删除的。但是如果我是删除表C的数据时,也应该能删除表D的数据,我建立一个类似于表B的触发器,删除表C的数据能正常删除表D,但是从表A开始删除的时候。就会出错误了,表D的数据删除和预计不一样了。多删除了一些数据,
leejelen 2010-06-23
  • 打赏
  • 举报
回复
DELETED 是代表什么啊?自带的函数么?代表当前需要操作删除的数据记录?
永生天地 2010-06-23
  • 打赏
  • 举报
回复
nightmaple 2010-06-23
  • 打赏
  • 举报
回复
如果你想用触发器,就要建两个,另一个建在tb_level2表上,代码如下
create trigger tri_a ON tb_level2
FOR delete
AS
begin
delete tb_level3 where level2Id in (SELECT level2Id FROM DELETED)
end
go
nightmaple 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 htl258 的回复:]
引用 3 楼 leejelen 的回复:
引用 2 楼 nightmaple 的回复:
你上次不是问过了么?
SQL code
create trigger tri_a ON tb_level1
FOR delete
AS
begin
delete tb_level3 where level2Id in (select level2Id from tb_level2 where l……
用外键级联删除就不需要建两个触发器。[/Quote]

他说的对,你试试建主外键吧,这个方法比较好
htl258_Tony 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 leejelen 的回复:]
引用 2 楼 nightmaple 的回复:
你上次不是问过了么?
SQL code
create trigger tri_a ON tb_level1
FOR delete
AS
begin
delete tb_level3 where level2Id in (select level2Id from tb_level2 where level1Id in (SELECT lev……
[/Quote]
用外键级联删除就不需要建两个触发器。
htl258_Tony 2010-06-23
  • 打赏
  • 举报
回复
--> 生成测试数据表: [tb_level1]
IF OBJECT_ID('[tb_level1]') IS NOT NULL
DROP TABLE [tb_level1]
GO
CREATE TABLE [tb_level1] ([level1Id] [int] PRIMARY KEY,[name] [nvarchar](10))
INSERT INTO [tb_level1]
SELECT '1','a' UNION ALL
SELECT '2','b'

--> 生成测试数据表: [tb_level2]
IF OBJECT_ID('[tb_level2]') IS NOT NULL
DROP TABLE [tb_level2]
GO
CREATE TABLE [tb_level2] ([level2Id] [int] PRIMARY KEY,[name] [nvarchar](10),[level1Id] [int] REFERENCES [tb_level1]([level1Id]) ON DELETE CASCADE)
INSERT INTO [tb_level2]
SELECT '1','aa','1' UNION ALL
SELECT '2','ab','1' UNION ALL
SELECT '3','ba','2' UNION ALL
SELECT '4','bb','2'

--> 生成测试数据表: [tb_level3]
IF OBJECT_ID('[tb_level3]') IS NOT NULL
DROP TABLE [tb_level3]
GO
CREATE TABLE [tb_level3] ([level3Id] [int],[name] [nvarchar](10),[level2Id] [int] REFERENCES [tb_level2]([level2Id]) ON DELETE CASCADE)
INSERT INTO [tb_level3]
SELECT '1','aaa','1' UNION ALL
SELECT '2','aab','1' UNION ALL
SELECT '3','aba','2' UNION ALL
SELECT '4','abb','2' UNION ALL
SELECT '5','baa','3' UNION ALL
SELECT '6','bba','4'

--SELECT * FROM [tb_level1]
--SELECT * FROM [tb_level2]
--SELECT * FROM [tb_level3]

-->SQL查询如下:
DELETE [tb_level1] WHERE level1Id=1

SELECT * FROM [tb_level1]
/*
level1Id name
----------- ----------
2 b

(1 行受影响)
*/
SELECT * FROM [tb_level2]
/*
level2Id name level1Id
----------- ---------- -----------
3 ba 2
4 bb 2

(2 行受影响)
*/
SELECT * FROM [tb_level3]
/*
level3Id name level2Id
----------- ---------- -----------
5 baa 3
6 bba 4

(2 行受影响)
*/
leejelen 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 nightmaple 的回复:]
你上次不是问过了么?
SQL code
create trigger tri_a ON tb_level1
FOR delete
AS
begin
delete tb_level3 where level2Id in (select level2Id from tb_level2 where level1Id in (SELECT level1Id FROM DELETED)
……
[/Quote]

对啊。但是又有问题了,你这里的话。是当我删除A表的时候,会删除掉下面两级。但是我直接删除B表的数据,那B表也不是要建索引么?
nightmaple 2010-06-23
  • 打赏
  • 举报
回复
你上次不是问过了么?
create trigger tri_a ON tb_level1
FOR delete
AS
begin
delete tb_level3 where level2Id in (select level2Id from tb_level2 where level1Id in (SELECT level1Id FROM DELETED)
delete tb_level2 where level1Id in (SELECT level1Id FROM DELETED)
end
go
永生天地 2010-06-23
  • 打赏
  • 举报
回复
1、可以用外键的级联删除设置,即可自动删除关联数据
实验五 触发器实验报告 [实验目的] 1. 理解Oracle触发器的种类和用途 2. 掌握行级触发器的编写 [预备知识] 1. PL/SQL程序设计 [实验原理] 1. 建立触发器 CREATE [OR REPLACE] TRIGGER <触发器名> BEFORE"AFTER INSERT"DELETE"UPDATE OF <列名> ON <名> [FOR EACH ROW] WHEN (<条件>) ON 子句中的名称识别与数据触发器关联数据 触发器事件指定了影响的 SQL DML 语句 ( INSERT、 DELETE 或 UPDATE) AFTER 指定了触发器在处理完成后触发 BEFORE 指定了触发器在处理完成前触发 默认情况下,触发器每个触发一次 FOR EACH ROW 选项指定触发器每行触发一次(即触发器为行级触发器) 要使触发器触发,WHEN 子句中布尔型达式的值必须判定为 TRUE 可以将 REPLACE 添加到 CREATE 语句以自动删除和重建触发器 2. 行级触发器中引用数据 在行级触发器中,使用伪记录来示旧数据:old和新数据:new 引用示例::new.customer_name, :old.customer_name 3. 行级触发器中的谓词 在一个多条件触发的触发器中,使用谓词可以区分当前触发的操作的类型:inserting, updating,deleting。 示例: IF Inserting THEN 语句 ; END IF; IF Updating THEN 语句 ; END IF; IF Deleting THEN 语句 ; END IF; 4. 触发器的限制 SELECT 语句必须是 SELECT INTO 语句或内部游标声明。 行级触发器不可以对触发进行查询,包括其调用的子过程中。 不允许 DDL 声明和事务控制语句 。 如果由触发器调用存储子过程,则存储子程序不能包括事务控制语句 。 :old 和 :new 值的类型不能是 LONG 和 LONG RAW。 [实验内容] 1. 给Customer增加一列Savings,类型为int,来存放每个顾客的存款总额。 ALTER TABLE customer ADD (saving varchar2(30)); select * from customer; 2. 更新Customer,使得Savings字段的值正确。 3. 在Account上增加一个行级触发器,当对account的balance进行update和insert一个 记录时同步修改Customer的Savings字段,保证数据的一致性。 4. 对account进行update操作,记录account和customer的变化。 5. 去掉顾客- 存款账号中引用account的外键约束(如果不去掉,后面的操作无法实现。当然最 佳的方法是修改其外键约束的更新策略,但考虑到复杂性,这里使用不标准的做法, 但建议大家实际运用中不要这么做)。在顾客- 存款账号插入一条记录,明顾客开设了一个新的账户。 6. 将一条刚才新开账户号的存款记录插入账号,记录account和customer的变化。 [实验总结] 1. 实验中遇到的问题和解决的方法。 ----------------------- "触发事件 ":old ":new " "Insert "无定义,所有字段都是N"该语句完成后插入的值 " " "ULL " " "Update "更新前该行的旧值 "更新后该行的值 " "Delete "删除前该行的值 "无定义,所有字段都是N" " " "ULL "

22,207

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧