我有两个表(T1和T2),T2.T1_ID引用T1.ID.我正在尝试使用触发器对T1中的行删除操作进行操作,这样如果T2中没有对T1行的引用,则删除T1行。否则,它只是在T1行的HIDDEN列上设置一个标志值。我已经尝试通过检查T2匹配引用来做到这一点,如果是这样,我引发一个异常取消删除并尝试设置标志,但它似乎不起作用。编译触发器时,我收到错误
“ORA-04084:无法更改此触发类型的新值”
我猜这与我在删除操作期间尝试更改数据这一事实有关。我尝试过类似问题的“删除后”触发器。这是我想要做的一个简单的例子:
create table "T1" (
"ID" number not null enable,
"HIDDEN" number,
constraint "T1_PK" primary key ("ID")
);
create table "T2" (
"T1_ID" number not null enable,
"VAL" number,
constraint "T2_FK1" foreign key ("T1_ID") references "T1" ("ID") enable
);
create or replace trigger "BD_T1"
before delete on "T1"
for each row
declare
cnt NUMBER;
records_found EXCEPTION;
begin
select count(*) into cnt from T2 where T1_ID = :OLD."ID";
if cnt > 0 then
RAISE records_found;
end if;
exception
when records_found then
:NEW."HIDDEN" := 1; -- set hidden flag and abort delete operation
end;
insert into T1 ("ID") values (1);
insert into T1 ("ID") values (2);
insert into T2 ("T1_ID", "VAL") values (1, 100);
insert into T2 ("T1_ID", "VAL") values (1, 200);
select * from T1;
delete from T1 where ID = 2; --no references so row deleted
select * from T2;
delete from T1 where ID = 1; -- references found so abort delete and set hidden flag`
答案 0 :(得分:1)
基本上,您的触发器正在尝试将DELETE语句更改为UPDATE语句。你不能做这个!但是,您可以通过完全消除触发器来完成所需的操作,并使用带有delete选项的MERGE语句替换DELETE语句。尝试:
merge into t1
using (select 1 t1id from dual
union all
select 2 t1id from dual) t
on (t1.id = t.t1id)
when matched then
update set t1.hidden = 1
delete where not exists
(select null from t2 where t2.t1_id = t1id);
答案 1 :(得分:0)
基本上,您的触发器正在尝试将DELETE语句更改为UPDATE语句。你不能做这个!但是,您可以通过完全消除触发器来完成所需的操作,并使用带有delete选项的MERGE语句替换DELETE语句。尝试:
merge into t1
using (select 1 t1id from dual
union all
select 2 t1id from dual) t
on (t1.id = t.t1id)
when matched then
update set t1.hidden = 1
delete where not exists
(select null from t2 where t2.t1_id = t1id);