编译无效对象
1、数据库对象失效的原因很多,下面大致归纳了一些常见的原因:
(1)当被引用对象的结构变更时,都会使得相关的依赖对象转变为INVALID状态。数据库中的对象(存储过程,函数,包,视图,触发器),它们往往需要直接或者间接的引用其它对象,对象的依赖包括直接和间接二种,其中直接依赖是指存储对象直接依赖于被引用对象,而间接依赖是指对象间接依赖于被引用对象
要查看被引用的对象,可以通过下面SQL查看
select * from dba_dependencies where name='&objectname';
举个简单例子,视图V_TEST引用了表TEST,TEST表修改了表结构时,会导致视图V_TEST变为无效对象。
CREATE TABLE TEST ( ID NUMBER(10)); CREATE VIEW V_TEST AS SELECT * FROM TEST; ALTER TABLE TEST ADD NAME VARCHAR(12); SELECT OBJECT_NAME, STATUS FROM DBA_OBJECTS WHERE OBJECT_NAME='V_TEST';
其实不管视图,像存储过程,函数、包等,如果代码本身没有什么错误,只是引用的对象发生了变化。也会失效。但并不影响调用,因为ORACLE在调用时会自动重新编译的,如果其它对象变化后导致编译有错误。这时调用时重新编译后也是错误并处于失效状态,所以调用会出错。
(2)发布SQL脚本时(包、存储过程、函数等),没有充分测试,编译时出错,这时对象变为无效。
(3) 数据库升级、迁移时,出现大量无效对象(本质原因,个人臆测归结为原因1)。
(4) 诸如此类各种情况:例如,Oracle 会自动维护分区索引,对于全局索引,如果在对分区表操作时,没有指定update index,则会导致全局索引失效,需要重建。
2、编译失效对象的方法
---统计失效的对象数:
select owner, object_type, status, count(*) from dba_objects where status='INVALID' group by owner, object_type, status order by owner, object_type;
---查看具体失效对象
col owner for a20; col object_name for a32; col object_type for a16 col status for a8 select owner, object_name, object_type, status from dba_objects where status='INVALID' order by 1, 2,3;
---编译无效对象方法一:
set heading off; set feedback off; set echo off; Set lines 999; spool run_invalid.sql select 'ALTER ' || OBJECT_TYPE || ' ' || OWNER || '.' || OBJECT_NAME || ' COMPILE;' from dba_objects where status = 'INVALID' and object_type in ('PACKAGE','FUNCTION','PROCEDURE','TRIGGER','JAVA SOURCE','JAVA CLASS','') ; spool off; set heading on; set feedback on; set echo on; @run_invalid.sql
---编译无效对象方法二:
dbms_utility.compile_schema('feng',false);
|
compile_all |
If TRUE, will compile everything within the schema regardless of whether it is VALID If FALSE, will compile only INVALID objects |
---编译无效对象方法三:
执行@$ORACLE_HOME/rdbms/admin/utlrp.sql脚本编译数据库失效对象。 许多情况下,由于数据库的升级或迁移,会导致数据库中的对象失效。由于对象之间可能存在复杂的倚赖关系,所以手工编译通常无法顺利通过。通常我们会在Oracle的升级指导中看到这个脚本,Oracle强烈推荐
在migration/upgrade/downgrade之后,通过运行此脚本编译失效对象。但是注意,Oracle提醒,此脚本需要用SQLPLUS以SYSDBA身份运行,并且当时数据库中最好不要有活动事物或DDL操作,
否则极容易导致死锁的出现。 另外,utlrp.sql 里面其实调用了$ORACLE_HOME/rdbms/admin/utlrcmp.sql来编译失效对象。
---oracle失效对象定期自动编译脚本
--1、创建自动编译失效过程事务记录表 declare tabcnt integer := 0; begin select count(*) into tabcnt from dba_tables where table_name='RECOMPILE_LOG'; if tabcnt = 0 then execute immediate 'create table recompile_log(rdate date,errmsg varchar2(200))'; end if; end; / --2、创建编译失效对象的存储过程 create or replace procedure recompile_invalid_objects as str_sql varchar2(200); --中间用到的sql语句 p_owner varchar2(20); --所有者名称,即SCHEMA errm varchar2(200); --中间错误信息 begin /*****************************************************/ p_owner := 'owner';/***用户名*************************/ /*****************************************************/ insert into recompile_log(rdate, errmsg) values(sysdate,'time to recompile invalid objects'); --编译失效存储过程 for invalid_procedures in (select object_name from all_objects where status = 'INVALID' and object_type = 'PROCEDURE' and owner=upper(p_owner)) loop str_sql := 'alter procedure ' ||invalid_procedures.object_name || ' compile'; begin execute immediate str_sql; exception When Others Then begin errm := 'error by obj:'||invalid_procedures.object_name||' '||sqlerrm; insert into recompile_log(rdate, errmsg) values(sysdate,errm); end; end; end loop; --编译失效函数 for invalid_functions in (select object_name from all_objects where status = 'INVALID' and object_type = 'FUNCTION' and owner=upper(p_owner)) loop str_sql := 'alter function ' ||invalid_functions.object_name || ' compile'; begin execute immediate str_sql; exception When Others Then begin errm := 'error by obj:'||invalid_functions.object_name||' '||sqlerrm; insert into recompile_log(rdate, errmsg) values(sysdate,errm); end; end; end loop; --编译失效包 for invalid_packages in (select object_name from all_objects where status = 'INVALID' and object_type = 'PACKAGE' and owner=upper(p_owner)) loop str_sql := 'alter package ' ||invalid_packages.object_name || ' compile'; begin execute immediate str_sql; exception When Others Then begin errm := 'error by obj:'||invalid_packages.object_name||' '||sqlerrm; insert into recompile_log(rdate, errmsg) values(sysdate,errm); end; end; end loop; --编译失效类型 for invalid_types in (select object_name from all_objects where status = 'INVALID' and object_type = 'TYPE' and owner=upper(p_owner)) loop str_sql := 'alter type ' ||invalid_types.object_name || ' compile'; begin execute immediate str_sql; exception When Others Then begin errm := 'error by obj:'||invalid_types.object_name||' '||sqlerrm; insert into recompile_log(rdate, errmsg) values(sysdate,errm); end; end; end loop; --编译失效索引 for invalid_indexs in (select object_name from all_objects where status = 'INVALID' and object_type = 'INDEX' and owner=upper(p_owner)) loop str_sql := 'alter index ' ||invalid_indexs.object_name || ' rebuild'; begin execute immediate str_sql; exception When Others Then begin errm := 'error by obj:'||invalid_indexs.object_name||' '||sqlerrm; insert into recompile_log(rdate, errmsg) values(sysdate,errm); end; end; end loop; --编译失效触发器 for invalid_triggers in (select object_name from all_objects where status = 'INVALID' and object_type = 'TRIGGER' and owner=upper(p_owner)) loop str_sql := 'alter trigger ' ||invalid_triggers.object_name || ' compile'; begin execute immediate str_sql; exception When Others Then begin errm := 'error by obj:'||invalid_triggers.object_name||' '||sqlerrm; insert into recompile_log(rdate, errmsg) values(sysdate,errm); end; end; end loop; end; / --3、创建任务计划,每天早上8点整执行该任务,且保证此任务有且只有一个 declare jobcnt integer :=0; job_recompile number := 0; str_sql varchar2(200); begin select count(*) into jobcnt from all_jobs where what = 'recompile_invalid_objects;' and broken = 'N'; if jobcnt > 0 then for jobs in (select job from all_jobs where what = 'recompile_invalid_objects;' and broken = 'N') loop str_sql := 'begin dbms_job.remove('||jobs.job||'); end;'; begin execute immediate str_sql; exception When Others Then null; end; end loop; end if; --创建任务计划 dbms_job.submit(job_recompile,'recompile_invalid_objects;',sysdate,'TRUNC(SYSDATE + 1) + 8/24'); --启动任务计划 dbms_job.run(job_recompile); end;

浙公网安备 33010602011771号