触发从另一个表中删除行

时间:2019-12-30 15:04:17

标签: sql database oracle plsql

我有两个表,分别是FORUM和COMMENTS

论坛主键:论坛

注释外键:FORUMID

,并且用户要删除论坛中的任何行时,必须执行触发器并首先删除该论坛中的评论

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正在变异,触发器/函数可能看不到它”。有什么办法解决吗?谢谢

4 个答案:

答案 0 :(得分: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 | USER_ID
-------: | ------:
       1 |       1
       2 |       2
select * from comments;
COMMENT_ID | FORUM_ID
---------: | -------:
         1 |        1
         2 |        1
         3 |        2
delete from forums where forum_id = 1;
1 rows affected

select * from comments;
COMMENT_ID | FORUM_ID
---------: | -------:
         3 |        2

答案 1 :(得分:0)

您可以将其转换为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;
/

答案 2 :(得分:0)

我不明白为什么您要为此使用两个查询。逻辑似乎是:

BEGIN
   DELETE COMMENTS
   WHERE FORUMID = :OLD.forumID;
END;

答案 3 :(得分:0)

我认为您可能在这里重新发明了轮子。您只需将外键定义为on delete cascade,然后让数据库为您完成繁重的工作即可:

ALTER TABLE comments
ADD CONSTRAINT fk_forum
FOREIGN KEY (forumid)
REFERENCES forum(forumid)
ON DELETE CASCADE