在日常数据库维护过程中,我们会发现数据库中一些对象(包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; 

参考资料:

http://jzhil2004.blog.163.com/blog/static/275585042010117113214172/

http://blog.csdn.net/tianlesoftware/article/details/4843600

http://www.233.com/oracle/jishu/20071014/101911246.html

ORACLE编译失效对象小结的更多相关文章

  1. oracle编译 失效对象方式

    如果procedure 所使用的表结构发生了改变等其它情况,在相应的xxx_objects表的status字段会变为invalid状态,但是如果在调用时procedure会自动编译,grant失效对象 ...

  2. sqlplus编译失效对象

    原文整理自:http://www.51testing.com/?uid-16403-action-viewspace-itemid-98161:http://www.eygle.com/archive ...

  3. oracle 编译无效对象

    在数据库中,会存在一些无效的对象,导致这种现象的发生原因很多,其中最常见的就是数据库升级(例如修改了表的结构),迁移而引起. 编译无效对象的方式: 1 使用alter **** compile 语句进 ...

  4. oracle重新编译失效对像

    重新编译失效对像可执行utlrp.sql文件: SQL> @?/rdbms/admin/utlrp.sql TIMESTAMP --------------------------------- ...

  5. oracle 索引失效原因及解决方法

    oracle 索引失效原因及解决方法 2010年11月26日 星期五 17:10 一.以下的方法会引起索引失效 ‍1,<>2,单独的>,<,(有时会用到,有时不会)3,like ...

  6. oracle 编译中一个关于clntsh 库的一个 帖子 ,收藏!

    oracle 编译中一个关于clntsh 库的一个 帖子 ,收藏! ------------------------------------------------------------------ ...

  7. oracle 索引失效原因

    转自  http://www.cnblogs.com/orientsun/archive/2012/07/05/2577351.html Oracle 索引的目标是避免全表扫描,提高查询效率,但有些时 ...

  8. Oracle 用户、对象权限、系统权限

    --================================ --Oracle 用户.对象权限.系统权限 --================================  一.用户与模式 ...

  9. 能使 Oracle 索引失效的六大限制条件【转】

    . 引用自: http://www.cnblogs.com/orientsun/archive/2012/07/05/2577351.html  总结得非常到位 Oracle 索引的目标是避免全表扫描 ...

随机推荐

  1. canvas学习(一)

    Canvas 学习之路 (一) canvas 是H5 里面神一样的东西,使得只是通过html和js就能做出非常棒的游戏和画面. 因为对前端无限的爱好,更加对canvas充满好奇,将我学习canvas的 ...

  2. 使用Spire.Doc来转换文本

    使用Spire.Doc来转换文本 前段时间,我为不熟悉这个产品的读者们写了一篇关于我对 Spire.Doc的初识印象.Spire.Doc是一个专业的Word .NET库,它是专门为开发人员设计的用来快 ...

  3. Azure Media Service (1) 使用OBS进行Azure Media Service直播

    <Windows Azure Platform 系列文章目录> 今天正好有客户问如何使用OBS进行Azure Media Service直播,我这里简单介绍一下. 先决条件: 1. OBS ...

  4. Compensating Transaction Pattern(事务修正模式)

    Undo the work performed by a series of steps, which together define an eventually consistent operati ...

  5. WCF 中 TCP 与 HTTP 性能简单比较

    在使用 WCF 时,为了更好地进行调试,我都选择了 HTTP 协议进行数据传输.最近项目对性能要求比较高,所以就换成了使用 TCP 协议.并对二者的性能进行了一个简单的测试.以下是测试结果: 环境: ...

  6. C#开发微信门户及应用(41)--基于微信开放平台的扫码登录处理

    在现今很多网站里面,都使用了微信开放平台的扫码登录认证处理,这样做相当于把身份认证交给较为权威的第三方进行认证,在应用网站里面可以不需要存储用户的密码了.本篇介绍如何基于微信开放平台的扫码进行网站的登 ...

  7. 百度编辑器UEditor常用设置函数大全

    在线文档对UEditor说明不够全面,收集了一些常用的方法和基本设置,以供参考.1.创建编辑器UE.getEditor('editor', { initialFrameWidth:"100% ...

  8. ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析

    ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Core整个WCF host. 因 ...

  9. 【C#进阶系列】29 混合线程同步构造

    上一章讲了基元线程同步构造,而其它的线程同步构造都是基于这些基元线程同步构造的,并且一般都合并了用户模式和内核模式构造,我们称之为混合线程同步构造. 在没有线程竞争时,混合线程提供了基于用户模式构造所 ...

  10. Xml的简单介绍和Xml格式

    XML 被设计用来结构化.存储以及传输信息.HTML 被设计用来显示数据. 1.XML是什么? 1)XML 指可扩展标记语言(EXtensible Markup Language) 2)XML 是一种 ...