我有卖火车票的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
答案 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
;如果它们相同(这可能是主键),那很好,但看起来很奇怪。