ORACLE编译失效对象


ORACLE编译失效对象

数据库对象失效原因
数据库对象失效的原因很多,下面大致归纳了一些常见的原因:

1: 当被引用对象的结构变更时,都会使得相关的依赖对象转变为INVALID状态。
数据库中的对象(存储过程,函数,包,视图,触发器),它们往往需要直接或者间接的引用其它对象,对象的依赖包括直接和间接二种,其中直接依赖是指存储对象直接依赖于被引用对象,而间接依赖是指对象间接依赖于被引用对象
要查看被引用的对象,可以通过下面SQL查看
SELECT   FROM   dba_dependencies  WHERE   NAME   '&objectname'   ;

SELECT   FROM   all_dependencies  WHERE   NAME   '&objectname'   ;

SELECT   FROM   user_dependencies  WHERE   NAME   '&objectname'   ;

其实不管视图,像存储过程,函数、包等,如果代码本身没有什么错误,只是引用的对象发生了变化。也会失效。但并不影响调用,因为ORACLE在调用时会自动重新编译的,如果其它对象变化后导致编译有错误。这时调用时重新编译后也是错误并处于失效状态,所以调用会出错。
2:发布SQL脚本时(包、存储过程、函数等),没有充分测试,编译时出错,这时对象变为无效。
3: 数据库升级、迁移时,出现大量无效对象(本质原因,个人臆测归结为原因1)。
4: 诸如此类各种情况:例如,Oracle 会自动维护分区索引,对于全局索引,如果在对分区表操作时,没有指定update index,则会导致全局索引失效,需要重建。

编译失效对象的方法
统计失效的对象:
SELECT  owner, object_name, object_type, status
   FROM  dba_objects
   WHERE  status =  'INVALID'
   ORDER   BY   1   2 3  ;

编译失效的对象:
1:   使用ALTER *** COMPLIE语句手工进行编译,这个适用于少数、个别对象失效
        alter package <schema name>.<package_name> compile;

        alter package <schema name>.<package_name> compile body;

        alter view <schema name>.<view_name> compile;

       alter trigger <schema).<trigger_name> compile;

2:执行@$ORACLE_HOME/rdbms/admin/utlrp.sql脚本编译数据库失效对象。
许多情况下,由于数据库的升级或迁移,会导致数据库中的对象失效。由于对象之间可能存在复杂的倚赖关系,所以手工编译通常无法顺利通过。通常我们会在Oracle的升级指导中看到这个脚本,Oracle强烈推荐在migration/upgrade/downgrade之后,通过运行此脚本编译失效对象。但是注意,Oracle提醒,此脚本需要用SQLPLUS以SYSDBA身份运行,并且当时数据库中最好不要有活动事物或DDL操作,否则极容易导致死锁的出现(这是很容易理解的)。
Oracle highly recommends running this script towards the end of of any migration/upgrade/downgrade.
另外,utlrp.sql 里面其实调用了$ORACLE_HOME/rdbms/admin/utlrcmp.sql来编译失效对象。

3:ORACLE提供了自动编译的接口dbms_utility.compile_schema(user,false); 调用这个过程就会编译所有失效的过程、函数、触发器、包
exec dbms_utility.compile_schema( 'SCOTT' )

4:SQL1:
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  ;
 

SQL2:
DECLARE
  v_objname user_objects.object_name%   TYPE  ;
  v_objtype user_objects.object_type%   TYPE  ;
   CURSOR  cur  IS
     SELECT  object_name, object_type
       FROM  user_objects
      WHERE  status =  'INVALID'
        AND  object_type  IN   (  'FUNCTION' ,
                            'JAVA SOURCE'  ,
                            'JAVA CLASS'  ,
                            'PROCEDURE'  ,
                            'PACKAGE'  ,
                            'TRIGGER'  );
BEGIN
   OPEN  cur;
   LOOP
     FETCH  cur
       INTO  v_objname, v_objtype;
 
     EXIT   WHEN   cur%  NOTFOUND ;
     BEGIN
       EXECUTE   IMMEDIATE   'alter '  || v_objtype ||  ' '  || v_objname ||
                         ' Compile'  ;
      dbms_output.put_line(   '编译'  || v_objtype ||  ' '   || v_objname ||  '()成功'  );
     EXCEPTION
       WHEN   OTHERS   THEN
        dbms_output.put_line(   '编译'  || v_objtype ||  ' '   || v_objname ||
                              '()失败.'  ||  SQLERRM   );
     END  ;
   END   LOOP  ;
   CLOSE  cur;
END  ;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值