急:ora-04098:触发器无效且未通过重新确认

ycyez 2013-02-22 10:43:24
我要对一张表,在写的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';
...全文
5135 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ycyez 2013-03-13
  • 打赏
  • 举报
回复
引用 10 楼 edcvf3 的回复:
其实包和第一个触发器我不知道你干嘛用的 完全可以去掉: 触发器这么写就可以了: SQL code?123456create or replace trigger tri_upd before update on test_4 for each rowbegin :new.cc := 'zhi';end tri_upd;
为什么会这么写?是因为,我在实际应用中,在更新某一行数据后,日期自动更新,按我的想法,只有先更新了(比如ID为3的)数据,触发器才知道应该把新的日期更新到ID为3的这条数据上。 所以我一直想着触发器的解发点是更新完某一条数据后,才解发事件。但我不太明白为啥你写的触发器是用befor,而不是after.
ycyez 2013-03-13
  • 打赏
  • 举报
回复
引用 10 楼 edcvf3 的回复:
其实包和第一个触发器我不知道你干嘛用的 完全可以去掉: 触发器这么写就可以了: SQL code?123456create or replace trigger tri_upd before update on test_4 for each rowbegin :new.cc := 'zhi';end tri_upd;
非常感谢你!~!! 我之前也向你这么写过,不知道为什么没有效果,可能是我写得有问题吧,不管怎么说,这个让我一直纠结的问题总算解决了。
Cryking 2013-03-07
  • 打赏
  • 举报
回复
其实包和第一个触发器我不知道你干嘛用的 完全可以去掉: 触发器这么写就可以了:

create or replace trigger tri_upd
  before update on test_4
  for each row
begin
  :new.cc := 'zhi';
end tri_upd;
Cryking 2013-03-07
  • 打赏
  • 举报
回复
额,不好意思,确实不是这个的问题,是因为存在递归 你触发器里使用UPDATE然后又触发了触发器,造成了死循环 update test_4 set cc = 'zhi' where aa = proc_testtrigger.p_aa;
Cryking 2013-03-07
  • 打赏
  • 举报
回复
引用 7 楼 ycyez 的回复:
引用 5 楼 edcvf3 的回复: 引用 4 楼 edcvf3 的回复:LZ竟然用包里的p_aa变量在两个触发器之间传递数值?? 变量作用域清楚吗? 额,不好意思,在同一SESSION下,包的全局变量是有效的. 不过你的包定义有点问题: create or replace package proc_testtrigger is p_aa test_4.aa%type; ……
加上 包就是无效的了, Compilation errors for PACKAGE SCOTT.PROC_TESTTRIGGER Error: PLS-00103: 出现符号 "BEGIN"在需要下列之一时: end function pragma procedure subtype type <an identifier> <a double-quoted delimited-identifier> current cursor delete exists prior Line: 4 Text: begin Error: PLS-00103: 出现符号 "end-of-file"在需要下列之一时: end not pragma final instantiable order overriding static member constructor map Line: 6 Text: end proc_testtrigger; ----------- 我就是去掉了BEGIN使包有效之后就可以成功执行的
ycyez 2013-03-07
  • 打赏
  • 举报
回复
引用 5 楼 edcvf3 的回复:
引用 4 楼 edcvf3 的回复:LZ竟然用包里的p_aa变量在两个触发器之间传递数值?? 变量作用域清楚吗? 额,不好意思,在同一SESSION下,包的全局变量是有效的. 不过你的包定义有点问题: create or replace package proc_testtrigger is p_aa test_4.aa%type; end p……
这个并没有什么问题,可以加上,也可以去掉。 现在最头疼的是怎么让这段程序执行成功。。
ycyez 2013-03-07
  • 打赏
  • 举报
回复
引用 3 楼 zjxpcyc 的回复:
好麻烦,为什么不直接创建 before 触发器?
没效果,都考虑过 -------------------------- 难道没有人做过对自身数据表进行DML操作的吗???
Cryking 2013-02-28
  • 打赏
  • 举报
回复
引用 4 楼 edcvf3 的回复:
LZ竟然用包里的p_aa变量在两个触发器之间传递数值?? 变量作用域清楚吗?
额,不好意思,在同一SESSION下,包的全局变量是有效的. 不过你的包定义有点问题: create or replace package proc_testtrigger is p_aa test_4.aa%type; end proc_testtrigger; 包头定义是不用BEGIN的
Cryking 2013-02-28
  • 打赏
  • 举报
回复
LZ竟然用包里的p_aa变量在两个触发器之间传递数值?? 变量作用域清楚吗?
yansen 2013-02-28
  • 打赏
  • 举报
回复
好麻烦,为什么不直接创建 before 触发器?
ycyez 2013-02-25
  • 打赏
  • 举报
回复
引用 1 楼 fw0124 的回复:
没有这种用法。 create or replace trigger tri_key before update on test_4 for each row begin :new.cc = 'zhi'; end tri_key; /
没有用啊,能否给一个完整的实例,谢谢!!!
fw0124 2013-02-22
  • 打赏
  • 举报
回复
没有这种用法。 create or replace trigger tri_key before update on test_4 for each row begin :new.cc = 'zhi'; end tri_key; /

17,140

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧