我需要解决突变表错误的帮助

时间:2020-04-09 15:40:48

标签: sql oracle triggers

我有下一个触发器

create or replace trigger Overwrite 
before insert on Comments 
Compound trigger 
declare

begin for each row 
declare
num number; 
begin

select count('x') into num
from comments
where title = :new.title 
and director = :new.director
and club = :new.club
and nick = :new.nick;

if num != 0 then
    delete from Comments
    where title = :new.title 
    and director = :new.director
    and club = :new.club
    and nick = :new.nick;
end if;
end;

当我进行大量插入时,我得到了突变表错误

insert into Membership(nick, club, mentor, type, req_date, inc_date, end_date, req_msg, acc_msg) values('davina', 'Fellowship of the Correct', 'adalbi', 'I', sysdate-2, sysdate, null, 'sdfghjhgfd', '23456543dcvbh'); 
insert into Proposals values ('O', 'Tim Blake Nelson', 'Fellowship of the Correct', 'davina', sysdate, 'asdkhaskd', 'lakshndlkjasdlkjasdfhasdjklhasdfjhkladfsjlhjklashjklds'); 
insert ALL 
    into comments (club, nick, msg_date, title, director, subject, message, valoration) values ('Fellowship of the Correct', 'ecp', sysdate-3, 'O', 'Tim Blake Nelson', 'asd', 'adsfasdfasdf', 10)
    into comments (club, nick, msg_date, title, director, subject, message, valoration) values ('Fellowship of the Correct', 'ecp', sysdate-2, 'O', 'Tim Blake Nelson', 'asd', 'adsfasdfdfghdfghasdf', 10)
    into comments (club, nick, msg_date, title, director, subject, message, valoration) values ('Fellowship of the Correct', 'ecp', sysdate-1, 'O', 'Tim Blake Nelson', 'asd', 'adsfasdfwertwerasdf', 10)
    into comments (club, nick, msg_date, title, director, subject, message, valoration) values ('Fellowship of the Correct', 'ecp', sysdate, 'O', 'Tim Blake Nelson', 'asd', 'adsfasdewrbtvwfasdf', 10)
select * from dual;

问题在于,当执行简单插入时,我没有突变表问题,但是当进行大量插入时,发生了突变表错误,我不十分清楚为什么会发生突变,并且也看不到如果有人知道并且可以向我解释如何修复它,以及它为什么会发生,那么如何修复它都是很好的。

谢谢

2 个答案:

答案 0 :(得分:0)

您为什么要使用触发器来实现应作为unique约束的条件?

alter table comments add constraint unq_comments_4
    unique (title, director, club, nick);

答案 1 :(得分:0)

虽然我同意另一个答案,即这不是实现此目标的最佳方法,但有一种方法可以实现。您在COMPOUND TRIGGER的指引下走在正确的道路上。检查一下:

CREATE OR REPLACE TRIGGER CMP_COMMENTS_DUP
FOR INSERT ON COMMENTS
COMPOUND TRIGGER
  TYPE lt_commentRows IS TABLE OF COMMENTS%ROWTYPE INDEX BY PLS_INTEGER;
  l_tComments lt_commentRows;
  l_nIndex INTEGER := 1;

  AFTER EACH ROW
  IS
  BEGIN
    l_tComments(l_nIndex).title:= :NEW.title;
    l_tComments(l_nIndex).director:= :NEW.director;
    l_tComments(l_nIndex).club:= :NEW.club;
    l_tComments(l_nIndex).nick:= :NEW.nick;
    l_nIndex := l_nIndex+1;
  END AFTER EACH ROW;

  AFTER STATEMENT IS
  BEGIN
    FORALL i IN INDICES OF l_tComments
      DELETE FROM comments c
      WHERE c.title= l_tComments(i).title
      AND c.director= l_tComments(i).director
      AND c.club= l_tComments(i).club
      AND c.nick= l_tComments(i).nick
      AND c.msg_date <> (SELECT MIN(c2.msg_date)
                         FROM comments c2
                         WHERE c2.title= l_tComments(i).title
                         AND c2.director= l_tComments(i).director
                         AND c2.club= l_tComments(i).club
                         AND c2.nick= l_tComments(i).nick);  
  END AFTER STATEMENT;
END;
/

这将在插入后为每一行填充关联数组。然后在AFTER STATEMENT部分(再次允许使用表操作)期间,它将删除重复的行,并保留最早的消息,直到msg_date。