Oracle 删除前触发

Oracle 删除前触发,oracle,plsql,ddl,database-trigger,dml,Oracle,Plsql,Ddl,Database Trigger,Dml,我创建了删除前触发器: create or replace trigger myTrigger3 before delete on emp for each row begin update emp set mgr = 'Null' where mgr = :old.emp_name; end; 桌子在哪里 emp(emp\u id整数主键、emp\u name varchar(20)、mgr varchar(20)) 但是当我运行这个语句时,触发器没有运行 delete from

我创建了删除前触发器:

create or replace trigger myTrigger3 
before delete on emp
for each row
begin
    update emp set mgr = 'Null' where mgr = :old.emp_name;
end;
桌子在哪里

emp(emp\u id整数主键、emp\u name varchar(20)、mgr varchar(20))

但是当我运行这个语句时,触发器没有运行

delete from emp where emp_id = 1004;
select * from emp;
错误报告-
ORA-04091:表DB20178004.EMP正在变异,触发器/函数可能看不到它
ORA-06512:在“DB20178004.MYTRIGGER3”的第2行
ORA-04088:执行触发器“DB20178004.MYTRIGGER3”时出错


您可以使用
set null
选项添加外键约束,而不是这样的触发器。当然,您需要的主键应该已经在
emp\u id
列中定义:

alter table emp 
add constraint fk_mgr foreign key(mgr)
references emp(emp_id)
on delete set null;
每当您删除带有
emp\u id
的记录时,如果该记录具有与
mgr
列匹配的值,则在删除带有该
emp\u id的记录后,这些记录将被清空

但请选择符合该列的
mgr
数据类型(数字)
emp_id
例如
integer
可以定义外键 约束

顺便说一下

  • 我建议您使用软删除。e、 g.向表中添加活动列,并 每当要删除时,将其值设置为零,并且不显示 应用程序上active=0的记录
  • 如果坚持删除,请不要按
    emp\u name
    列进行筛选,因为 可以有多个人使用相同的名字,但使用
    emp\u id
    最好是在表格中独一无二

当表的数据已经更改时,您无法操作表数据。您必须在delete语句之后更新表。一种方法是对每一行不使用
的after delete触发器,在该触发器中更新表中不再存在的所有管理器。另一种方法是使用复合触发器,在该触发器中,您可以在每一行之后的
部分记住所有已删除的ID,并在
语句之后的
部分中使用它们进行更新。另一方面:
set mgr='Null'
可能应该是
set mgr=Null
。您真的不想将mgr设置为包含单词“Null”的字符串,是吗?