ORACLE编译失效对象小结-阿里云开发者社区

开发者社区> 潇湘隐者> 正文

ORACLE编译失效对象小结

简介:
+关注继续查看

在日常数据库维护过程中,我们会发现数据库中一些对象(包Package、 存储过程Procedure、函数Function、视图View、同义词.....)会失效,呈现无效状态(INVALID)。有时候需要定期检查数据 库中存在哪些失效对象,对于存在异常的对象需要重新编译,有些自动失效的对象,一般会在下次调用的时候,会被重新编译,所以这些不需要人工干预。那么为什 么对象突然会失效呢?又如何快速、高效的编译失效对象呢?哪些失效的对象不需要我们去重新编译呢?

数据库对象失效原因

数据库对象失效的原因很多,下面大致归纳了一些常见的原因(有些漏掉的,希望大家补充):

1: 当被引用对象的结构变更时,都会使得相关的依赖对象转变为INVALID状态。

数据库中的对象(存储过程,函数,包,视图,触发器),它们往往需要直接或者间接的引用其它对象,对象的依赖包括直接和间接二种,其中直接依赖是指存储对象直接依赖于被引用对象,而间接依赖是指对象间接依赖于被引用对象

要查看被引用的对象,可以通过下面SQL查看

select * from dba_dependencies where name='&objectname';

    

select * from all_dependencies where name='&objectname';

 

select * from user_dependencies where name='&objectname';
举个简单例子,视图V_TEST引用了表TEST,TEST表修改了表结构时,会导致视图V_TEST变为无效对象。


SQL> CREATE TABLE TEST ( ID NUMBER(10));

 

Table created.

 

SQL> CREATE VIEW V_TEST AS SELECT * FROM TEST;

 

View created.

 

SQL> SELECT OBJECT_NAME, STATUS FROM DBA_OBJECTS WHERE OBJECT_NAME='V_TEST';

 

OBJECT_NAME STATUS

 

------------------- ----------------

 

V_TEST VALID

 

--修改表结构,增加一个字段NAME后,视图V_TEST变为无效

 

SQL> ALTER TABLE TEST ADD NAME VARCHAR(12);

 

Table altered.

 

SQL> SELECT OBJECT_NAME, STATUS FROM DBA_OBJECTS WHERE OBJECT_NAME='V_TEST';

 

OBJECT_NAME STATUS

 

------------------- ----------------

 

V_TEST INVALID

 

--查询视图V_TEST后,数据库会重新编译视图

 

SQL> SELECT * FROM V_TEST;

 

no rows selected

 

SQL> SELECT OBJECT_NAME, STATUS FROM DBA_OBJECTS WHERE OBJECT_NAME='V_TEST';

 

OBJECT_NAME STATUS

 

------------------- ----------------

 

V_TEST VALID

其实不管视图,像存储过程,函数、包等,如果代码本身没有什么错误,只是引用的对象发生了变化。也会失效。但并不影响调用,因为ORACLE在调用时会自动重新编译的,如果其它对象变化后导致编译有错误。这时调用时重新编译后也是错误并处于失效状态,所以调用会出错。

2:发布SQL脚本时(包、存储过程、函数等),没有充分测试,编译时出错,这时对象变为无效。

3: 数据库升级、迁移时,出现大量无效对象(本质原因,个人臆测归结为原因1)。

4: 诸如此类各种情况:例如,Oracle 会自动维护分区索引,对于全局索引,如果在对分区表操作时,没有指定update index,则会导致全局索引失效,需要重建。

 

编译失效对象的方法

统计失效的对象:


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;



下文大多参考博文Oracle中编译无效的对象常用方法,修改并作了总结、整理

 

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:  一些网友书写的编译失效对象(经过整理)

SQL 1: 编译失效对象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  

SQL 2:在上面的方法中,只能知道某某编译失败,不清楚失败原因,可以用PL/SQL实现更详细的错误信息

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; 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10018 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10880 0
Java面向对象高级--抽象类的基本概念------abstract
<h1>抽象类的概念:</h1> <p>包含一个抽象方法的类就称为抽象类。</p> <p>抽象方法:只声明但未实现的方法称为抽象方法,使用abstract关键字声明。</p> <h1>抽象类的定义及使用规则:</h1> <div> <img src="http://img.blog.csdn.net/20130925145338703" alt=""><br> </div> <d
1025 0
oracle 编译无效对象
1.手动编译 如果无效对象的数量很少,那么你可以逐个编译这些对象. 如 ALTER PACKAGE my_package COMPILE; ALTER PACKAGE my_package COMPILE BODY; ALTER PROCED...
1202 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13820 0
了解超然物外的static-方法篇 | 带你学《Java面向对象编程》之十一
本节简明赅要地指出了静态方法的一些使用场景与限制,并结合实际案例展示了一项static的用途。
1142 0
了解超然物外的static-属性篇 | 带你学《Java面向对象编程》之十
本节通过传统类与使用static的类之间的比较,突出了static对于存储超大量重复性数据的优异表现。
921 0
Iterator迭代器对象
目录: 》迭代器Iterator的使用 》迭代字符串集合 》迭代对象集合 》迭代器使用图解,和原理分析 》Java迭代器源代码 》迭代器Iterator的使用: 》迭代字符串集合 import java.
650 0
+关注
潇湘隐者
网名潇湘隐者/潇湘剑客、英文名Kerry,兴趣广泛,广泛涉猎,个性随意,不善言辞。执意做一名会写代码的DBA,混迹于IT行业
777
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载