ORA-04098错误解决方法


ORA-04098错误解决方法

数据库版本:8.1.5
平台:SOLARIS 5.7

背景:

用户建立了一个TRIGGER:
create or replace trigger ddl_deny
before create or alter or drop on database
declare
begin
insert into ddl_logs values(ora_dict_obj_owner,ora_dict_obj_name,sysdate);
exception
when no_data_found then
null;
end;
目的大概就是记录下所有的DDL操作,但TRIGGER建立有错误,发现:

11:30:08 system@ORA250>alter trigger ddl_deny disable;
alter trigger ddl_deny disable
*
ERROR 位于第 1 行:
ORA-04098: 触发器 'DDL_DENY' 无效且未通过重新验证
11:31:45 system@ORA250>drop trigger ddl_deny;
drop trigger ddl_deny
*
ERROR 位于第 1 行:
ORA-04098: 触发器 'DDL_DENY' 无效且未通过重新验证

此时触发器不能编译过去,也不能删除了,因为触发器本身里面定义了DDL操作的触发,产生ORA-04098: 触发器 'DDL_DENY' 无效且未通过重新验证。

解决方法:

1、首先查看用户的权限是否正确:

select owner, object_name, object_type, status from dba_objects where object_name = '

 1<trigger_name>';   
 2  
 312:42:38 system@ORA250&gt;select owner, object_name, object_type, status from dba_o   
 4bjects where object_name='DDL_DENY';   
 5OWNER OBJECT_NAME OBJECT_TYPE STATUS   
 6\------------------------------------ --------------   
 7SYSTEM DDL_DENY TRIGGER INVALID   
 8  
 9发现用户权限没有问题。   
10  
112、接着设置诊断事件alter session set events='4098 trace name errorstack level 3';,查看trace文件的内容如下:   
12  
13Dump file /db1/app/oracle/admin/ora250/udump/ora250_ora_6834.trc   
14Oracle8i Enterprise Edition Release 8.1.5.0.0 - Production   
15With the Partitioning and Java options   
16PL/SQL Release 8.1.5.0.0 - Production   
17ORACLE_HOME = /db1/app/oracle/product/8.1.5   
18System name: SunOS   
19Node name: db250   
20Release: 5.7   
21Version: Generic_106541-08   
22Machine: sun4u   
23Instance name: ora250   
24Redo thread mounted by this instance: 1   
25Oracle process number: 17   
26Unix process pid: 6834, image: oracle@db250 (TNS V1-V3)   
27*** SESSION ID30.829) 2004.11.17.20.53.38.000   
28*** 2004.11.17.20.53.38.000   
29ksedmp: internal or fatal error   
30ORA-04098: 触发器'DDL_DENY' 无效且未通过重新验证   
31Current SQL statement for this session:   
32alter trigger ddl_deny disable   
33\----- Call Stack Trace -----   
34calling call entry argument values in hex   
35location type point (? means dubious value)   
36\-------------------- -------- -------------------- ----------------------------   
37ksedmp()+160 CALL ksedst()+0 508 ? 1 ? FFBEB31C ?   
38FFBEADC0 ? FFBEADA4 ? 0 ?   
39ksddoa()+248 PTR_CALL 00000000 3 ? 0 ? 0 ? 16594FC ?   
40C0000025 ? 0 ?   
41ksdpcg()+212 CALL ksddoa()+0 16EB0AC ? 16E4C24 ? 3 ?   
4224939C ? 16EB0AC ? 16EB090 ?   
43ksdpec()+236 CALL ksdpcg()+0 1002 ? FFBEB8E4 ? 16E4C24 ?   
440 ? 0 ? 0 ?   
45ksfpec()+136 CALL ksdpec()+0 1002 ? 165A800 ? 165A800 ?   
467F3 ? 1659995 ? 16594FC ?   
47kgesev()+100 PTR_CALL 00000000 1659494 ? 1002 ? 262F80 ?   
481002 ? 1 ? 0 ?   
49ksesec1()+48 CALL kgesev()+0 1659494 ? 16E8CA4 ? 1002 ?   
501 ? FFBEBA60 ? 1 ?   
51kkttrex()+2112 CALL ksesec1()+0 1002 ? 1 ? 8 ? 8E859D26 ? 2 ?   
522 ?   
53kktexeevt()+616 CALL kkttrex()+0 8E996A20 ? 8E973B48 ?   
54FFBEBAE4 ? 1659000 ?   
558E859D6C ? 165E800 ?.....   
56  
57发现是内部严重错误,其他看不出太多错误信息,于是想到采用隐含参数_system_trigger_enabled=false,在数据库启动的时候让所有触发器不起作用,然后删除。数据库8.1.5的提示没这个参数,于是查询了一下:   
58  
5914:28:32 system@ORA815&gt;select ksppinm from x$ksppi where substr(ksppinm,1,1)='_'   
60and ksppinm like '%tri%' order by ksppinm;   
61KSPPINM   
62\-------------------------------------------------------------------------------   
63_cleanup_rollback_entries   
64_distributed_lock_timeout   
65_distributed_recovery_connection_hold_time   
66_number_cached_attributes   
67_system_trig_enabled   
68  
69发现8.1.5版本的参数是_system_trig_enabled,于是让用户在初始化参数文件中设置此参数为false,然后重启数据库,删除trigger,删除成功。   
70  
71至此问题解决。</trigger_name>
Published At
Categories with 数据库类
Tagged with
comments powered by Disqus