触发器从另一个表中删除行
Posted
技术标签:
【中文标题】触发器从另一个表中删除行【英文标题】:Trigger to delete row from another table 【发布时间】:2019-12-30 15:04:17 【问题描述】:我有两张表,分别是 FORUM 和 COMMENTS
论坛主键:论坛ID
评论外键:FORUMID
当用户想要删除论坛中的任何一行时,必须先执行触发器并删除该论坛中的 cmets
CREATE OR REPLACE trigger trg_delete_comments
BEFORE DELETE ON forum
FOR EACH ROW
DECLARE
v_forumID varchar(14);
v_user varchar(20);
BEGIN
select forumID into v_forumID
from forum
where forumID =:OLD.forumID;
DELETE COMMENTS
WHERE FORUMID = v_forumID;
END;
/
当我尝试执行此触发器时,我收到“ORA-04091:表 FORUM 正在变异,触发器/函数可能看不到它”的错误。有什么办法可以解决吗?谢谢
【问题讨论】:
【参考方案1】:您所描述的是可以通过外键约束轻松提供的功能。您可以使用on delete cascade
子句配置约束,以便在删除父记录时也删除子记录。
考虑the following example:
create table forums (
forum_id int primary key,
user_id int
);
create table comments (
comment_id int primary key,
forum_id int,
constraint fk_comments_forum
foreign key (forum_id)
references forums(forum_id)
on delete cascade
);
select * from forums;
FORUM_ID |用户身份
--------: | ------:
1 | 1
2 | 2
select * from comments;
COMMENT_ID |论坛ID
---------: | --------:
1 | 1
2 | 1
3 | 2
delete from forums where forum_id = 1;
1 rows affected
select * from comments;
COMMENT_ID |论坛ID
---------: | --------:
3 | 2
【讨论】:
【参考方案2】:我不明白您为什么为此使用两个查询。逻辑似乎是:
BEGIN
DELETE COMMENTS
WHERE FORUMID = :OLD.forumID;
END;
【讨论】:
是的,你是对的,我想我已经重复了两次相同的操作。谢谢【参考方案3】:您可以将其转换为 AFTER STATEMENT 触发器,然后可以删除行 -
CREATE OR REPLACE trigger trg_delete_comments
AFTER DELETE ON forum
BEGIN
DELETE COMMENTS
WHERE FORUMID IN (select forumID
from forum
where forumID = :OLD.forumID);
END;
/
【讨论】:
上述 after 语句将不起作用。 Old.column_name not New.column_name 列在语句级触发器中不可用。复合触发器,或者如果在您的版本上不可用,则可以使用一个包来模拟复合触发器。但是在 FK 上级联仍然比任何一个都容易得多。【参考方案4】:我认为您可能在这里重新发明***。您可以简单地将外键定义为on delete cascade
,然后让数据库为您完成繁重的工作:
ALTER TABLE comments
ADD CONSTRAINT fk_forum
FOREIGN KEY (forumid)
REFERENCES forum(forumid)
ON DELETE CASCADE
【讨论】:
以上是关于触发器从另一个表中删除行的主要内容,如果未能解决你的问题,请参考以下文章