我正在尝试运行这个触发器,它应该在每次修改Employee表时记录一个事务。
这是扳机
CREATE OR REPLACE TRIGGER EMPLOYEE_AUDIT_TRIGGER
BEFORE INSERT OR DELETE OR UPDATE ON EMPLOYEE
FOR EACH ROW
BEGIN
INSERT INTO TRANSACTIONS (TRANSACTION_TIMESTAMP, USERNAME, EMP_ID, POSITION_TYPE)
VALUES (SYSTIMESTAMP, GET_USERNAME(), :NEW.EMP_ID, 'HR');
END;
get_username函数只是我定义的一个普通函数,它返回当前用户的用户名。没有触发器,我可以在Employee表中输入employee而不会出现任何错误,所以这绝对不是一个错误,只是触发器出了问题
触发器应该记录一个事务
然而,我一直在犯这个错误:
ORA-02291: integrity constraint (xxxx.SYS_xxxxx) violated - parent key
not found
ORA-06512: at "xxxxx.EMPLOYEE_AUDIT_TRIGGER", line 2
ORA-04088: error during execution of trigger 'xxxxx.EMPLOYEE_AUDIT_TRIGGER'
2条答案
按热度按时间jchrr9hc1#
Oracle说你正在尝试插入一个在父表中不存在的值。
该 parent 表通过外键约束从
transactions
表引用。transaction_timestamp
可以username
:为什么不使用内置的user
函数?emp_id
:似乎可以; pseudorecord是这么说的。注意 old 和 new 值(当您删除行时,new不存在,因此可能需要使用coalesce(:new.emp_id, :old.emp_id)
)position_type
:什么是HR
?那列上有外键吗?是否存在于父表中?czq61nw12#
您有
transactions
表,其中包含DDL:你的触发点是
有三个问题:
1.它是一个
BEFORE INSERT
触发器,因此您试图在EMP_ID
存在于employee
表中之前将其插入transactions
表中,并且将没有行供引用约束引用(尚未)。您可以通过将触发器更改为AFTER INSERT
或推迟约束的计算来解决这个问题,但这不会解决下一个问题。1.它将在
DELETE
上触发,在这种情况下,包含EMP_ID
的行将从employee
表中删除,这将失败,因为transactions
表中有一个引用约束,要求父键存在。1.从
employee
表中删除行时,:NEW.EMP_ID
将是NULL
。要修复它,您需要:
transactions.emp_id
上的FOREIGN KEY
约束,因为您仍然希望事务在删除员工后仍然存在,并且约束是不必要的(并且是导致错误的原因)。INSERT
中将:NEW.EMP_ID
更改为COALESCE(:NEW.EMP_ID, :OLD.EMP_ID)
。LOGIN
和POSITIONS
表中删除行,那么您可能希望从transactions
表中删除所有外键,因为这些列可能会出现类似的问题。