由于游标,ORA-04091表名在触发器中发生变化

时间:2014-01-03 19:22:26

标签: oracle plsql triggers cursor

因此,当我编译以下脚本时,它会抛出变异表错误:

CREATE OR REPLACE TRIGGER SEND_MAIL
BEFORE DELETE
ON CATEGORIE
FOR EACH ROW
DECLARE 
bodytext  varchar2(100);

CURSOR getabonnee IS
SELECT CATEGORIEABONNEMENT.MAILABONNEEID, NAAM 
FROM CATEGORIE
INNER JOIN CATEGORIEABONNEMENT ON CATEGORIEABONNEMENT.CATEGORIENAAM = CATEGORIE.NAAM
WHERE NAAM = :old.NAAM;

CURSOR getabonneeinfo(p_id CATEGORIEABONNEMENT.MAILABONNEEID%TYPE) IS
SELECT MAILABONNEE.VOORNAAM, MAILABONNEE.ACHTERNAAM, MAILABONNEE.EMAILADRES
FROM CATEGORIEABONNEMENT
INNER JOIN MAILABONNEE ON MAILABONNEE.ID = CATEGORIEABONNEMENT.MAILABONNEEID
WHERE MAILABONNEEID = p_id;

BEGIN

   FOR cc IN getabonnee LOOP

      FOR cc2 IN getabonneeinfo(cc.MAILABONNEEID) LOOP

     bodytext := cc2.voornaam || cc2.achternaam || :old.NAAM;
     EXECUTE IMMEDIATE bodytext;

     SENDMAILABONNEE(bodytext, cc2.emailadres);

     DELETE FROM CATEGORIEABONNEMENT
     WHERE MAILABONNEEID = cc.MAILABONNEEID;

     UPDATE NIEUWSBERICHT
     SET CATEGORIENAAM = null
     WHERE CATEGORIENAAM = :old.NAAM;

  END LOOP;
END LOOP;
END;
/

savepoint deletecategory;

delete from Categorie where naam='Buitenland';

rollback to deletecategory;

我找到了这个错误的解决方案,发现人们建议使用复合触发器。问题是由于某种原因,我的数据库软件(Oracle SQL Developer)无法将复合触发器识别为有效单元。我检查了我的oracle版本,我有11g,所以我不太明白为什么它不起作用。任何人都有解决这个问题的方法吗?

1 个答案:

答案 0 :(得分:2)

在第一个游标中,不要在查询中包含CATEGORY表。触发器已经包含要删除的行中所有列的值,因此请将其更改为:

SELECT MAILABONNEEID 
  FROM CATEGORIEABONNEMENT
 WHERE CATEGORIEABONNEMENT.CATEGORIENAAM = :old.NAAM;