触发器不起作用(触发器执行期间出现ORA-04088错误)

时间:2014-03-21 23:05:52

标签: sql oracle

我有卖火车票的DB。我有表Ticket和表Cancel(这里是取消的票证)。我已经编写了一个触发器,如果​​我向表Cancel添加一些票据,那么此票证在表Ticket中设置为空闲(Client_id属性= NULL)。

但我想写一个新的:"如果我已取消票证(表票证中的Client_id = NULL),然后当我更新票证并设置Client_id =' some_number'(例如Client_id = 5),然后我应该从Cancel表中删除此票证。 这是我的触发器:

CREATE OR REPLACE TRIGGER Buy_Cancel
  AFTER UPDATE
  ON TICKET
  FOR EACH ROW
  WHEN(old.CLIENT_ID IS NULL)
DECLARE 
  rowAmmount INTEGER;
BEGIN 
  SELECT COUNT(*)
    INTO rowAmmount
    FROM CANCEL c JOIN TICKET t ON c.TICKET_ID = t.TICKET_ID
    WHERE t.TICKET_ID = :OLD.TICKET_ID;
  IF rowAmmount > 0 THEN 
    DELETE FROM CANCEL c
      WHERE c.TICKET_ID = :NEW.TICKET_ID;
  END IF;
END;

当我运行查询时:

UPDATE TICKET t
  SET t.CLIENT_ID = 5
  WHERE t.TICKET_ID = 2;

导致此类错误:

ORA-04091: table MYDB.TICKET is mutating, trigger/function may not see it
ORA-06512: at "MYDB.BUY_CANCEL", line 4
ORA-04088: error during execution of trigger 'MYDB.BUY_CANCEL' SQL6.sql 2 8 

1 个答案:

答案 0 :(得分:0)

不确定我是否完全理解您的逻辑,但错误是因为您在该表的触发器中查询ticket表。您不需要 - 加入似乎没有添加任何内容,因为您已经拥有了机票ID:

CREATE OR REPLACE TRIGGER Buy_Cancel
  AFTER UPDATE
  ON TICKET
  FOR EACH ROW
  WHEN(old.CLIENT_ID IS NULL)
DECLARE 
  rowAmmount INTEGER;
BEGIN 
  SELECT COUNT(*)
    INTO rowAmmount
    FROM CANCEL c
    WHERE c.TICKET_ID = :OLD.TICKET_ID;
  IF rowAmmount > 0 THEN 
    DELETE FROM CANCEL c
      WHERE c.TICKET_ID = :NEW.TICKET_ID;
  END IF;
END;

尽管如此,查询根本没什么意义;只是删除自己的删除。会工作 - 如果没有匹配的行,它就不会出错,所以它会简化它。并且您在:old中使用select,在删除中使用:new;如果它们相同(这可能是主键),那很好,但看起来很奇怪。