我要对一张表,在写的SQL语句时更新第二个字段,触发器自动更新第三个字段(需求是时间),结果提示
ora-04098:触发器“tri_key”无效且未通过重新确认。--对自身表触发修改
--创建表
drop table test_4;
create table test_4
(
aa varchar2(10),
bb varchar2(10),
cc varchar2(10)
);--第一步:创建程序包,设立全局变量
create or replace package proc_testtrigger
is
p_aa test_4.aa%type;
begin
null;
end proc_testtrigger;
/--第二步:创建行触发器,将key值存入全局变量中
create or replace trigger tri_key
after update on test_4 for each row
begin
proc_testtrigger.p_aa := :new.aa;
end tri_key;
/ --第三步:创建表触发器,根本全局变量更新数据
create or replace trigger tri_upd
after update on test_4
begin
update test_4 set cc = 'zhi' where aa = proc_testtrigger.p_aa;
end tri_upd;
/ --插入数据
insert into test_4 (aa, bb, cc) values ('a', 'b', '');
insert into test_4 (aa, bb, cc) values ('a', 'c', '');
insert into test_4 (aa, bb, cc) values ('a', 'e', '');
--SQL语句,更新语句 ,想实现在更新的同时,触发器更新CC字段
update test_4 set bb = 'gggg' where aa = 'a';自身表触发修改,ORA-04098UPDATE
ora-04098:触发器“tri_key”无效且未通过重新确认。--对自身表触发修改
--创建表
drop table test_4;
create table test_4
(
aa varchar2(10),
bb varchar2(10),
cc varchar2(10)
);--第一步:创建程序包,设立全局变量
create or replace package proc_testtrigger
is
p_aa test_4.aa%type;
begin
null;
end proc_testtrigger;
/--第二步:创建行触发器,将key值存入全局变量中
create or replace trigger tri_key
after update on test_4 for each row
begin
proc_testtrigger.p_aa := :new.aa;
end tri_key;
/ --第三步:创建表触发器,根本全局变量更新数据
create or replace trigger tri_upd
after update on test_4
begin
update test_4 set cc = 'zhi' where aa = proc_testtrigger.p_aa;
end tri_upd;
/ --插入数据
insert into test_4 (aa, bb, cc) values ('a', 'b', '');
insert into test_4 (aa, bb, cc) values ('a', 'c', '');
insert into test_4 (aa, bb, cc) values ('a', 'e', '');
--SQL语句,更新语句 ,想实现在更新的同时,触发器更新CC字段
update test_4 set bb = 'gggg' where aa = 'a';自身表触发修改,ORA-04098UPDATE
create or replace trigger tri_key
before update on test_4 for each row
begin
:new.cc = 'zhi';
end tri_key;
/
变量作用域清楚吗?
不过你的包定义有点问题:
create or replace package proc_testtrigger
is
p_aa test_4.aa%type;
end proc_testtrigger;
包头定义是不用BEGIN的
--------------------------
难道没有人做过对自身数据表进行DML操作的吗???
Compilation errors for PACKAGE SCOTT.PROC_TESTTRIGGERError: PLS-00103: 出现符号 "BEGIN"在需要下列之一时:
end function pragma
procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
exists prior
Line: 4
Text: beginError: PLS-00103: 出现符号 "end-of-file"在需要下列之一时:
end not pragma
final instantiable order overriding static member constructor
map
Line: 6
Text: end proc_testtrigger;
-----------
我就是去掉了BEGIN使包有效之后就可以成功执行的
你触发器里使用UPDATE然后又触发了触发器,造成了死循环
update test_4 set cc = 'zhi' where aa = proc_testtrigger.p_aa;
触发器这么写就可以了:create or replace trigger tri_upd
before update on test_4
for each row
begin
:new.cc := 'zhi';
end tri_upd;
为什么会这么写?是因为,我在实际应用中,在更新某一行数据后,日期自动更新,按我的想法,只有先更新了(比如ID为3的)数据,触发器才知道应该把新的日期更新到ID为3的这条数据上。
所以我一直想着触发器的解发点是更新完某一条数据后,才解发事件。但我不太明白为啥你写的触发器是用befor,而不是after.