重新编译数据库中的失效对象

原文整理自:http://www.51testing.com/?uid-16403-action-viewspace-itemid-98161;http://www.eygle.com/archives/2005/01/ecioaeaoeeeaoea.html

先看个帖子:http://www.itpub.net/thread-1112553-1-1.html

每次数据库做了升级(打各种数据库方面的补丁后,不是数据库本身的升级,是各种对象改变增加修改等,呵呵不,别误解)
完了以后我都要查一下数据库中的失效对象,每次都发现多了好多,尤其是包啊过程啊等,都要重新再编译一次,才全部都好了,有点奇怪,为什么总需要这样呢?
大家有这样的经历把,只要重新编译就OK了,不这样做,生产中一堆失效对象,不编译估计对生产有影响吧,系统用到这些包和过程等的时候,发现失效会自己去编译吗?

跟帖解答:你修改对象的操作导致了存储过程被置于invalid 状态。因为升级有一些DDL操作,导致相关存储过程失效。可以使用自带的重编译脚本$ORACLE_HOME/rdbms/admin/utlrp.sql ,存储过程再次使用的时候自动编译。但是,自动编译可能成功也可能失败,
升级完检查失效对象是好习惯。
更好的习惯是,更改对象之前先查看会影响哪些对象


1、查找无效对象
你可以根据这个查询结果来判断使用下面的哪种方法来编译你数据库里面的无效对象.

SQL> COLUMN  object_name  FORMAT  A30

SQL> SELECT owner,object_type,object_name,STATUS
FROM dba_objects WHERE
STATUS='INVALID' ORDER BY owner,object_type,object_name;

2、手动编译
如果无效对象的数量很少,那么你可以逐个编译这些对象.
如:

SQL> ALTER PACKAGE my_package COMPILE;
SQL> ALTER PACKAGE my_package COMPILE BODY;
SQL> ALTER PROCEDURE my_procedure COMPILE;
SQL> ALTER FUNCTION my_function COMPILE;
SQL> ALTER TRIGGER my_trigger COMPILE;
SQL> ALTER VIEW my_view COMPILE;

你也可以用DBMS_DDL包来编译(但只用于PL/SQL对象,所以你不用它来编译视图等):

SQL> EXEC DBMS_DDL('PACKAGE','MY_SCHEMA','MY_PACKAGE'); 
SQL> EXEC DBMS_DDL('PACKAGE BODY','MY_SCHEMA','MY_PACKAGE'); 
SQL> EXEC DBMS_DDL('PROCEDURE','MY_SCHEMA','MY_PROCEDURE'); 
SQL> EXEC DBMS_DDL('FUNCTION','MY_SCHEMA','MY_FUNCTION'); 
SQL> EXEC DBMS_DDL('TRIGGER','MY_SCHEMA','MY_TRIGGER');

3、通用脚本
在某些情况下你可能有很多无效对象要编译,这样话手工编译就显得效率太低了.
在这种情况下你可以些一个通用的脚本生成编译脚本.
下面的脚本用来查询无效的package 和package body并生成便宜这些对象的脚本.
但是这方法不会考虑ORACLE对象之间的依赖关系.

SQL>
SET SERVEROUTPUT ON SIZE 1000000 
 SQL>  BEGIN 

                   FOR cur_rec IN (SELECT owner,object_name,object_type,DECODE (object_type,'PACKAGE',1,'PACKAGE BODY',2,2)  AS  recompile_order   FROM  dba_objects  WHERE  object_type IN  ('PACKAGE','PACKAGE BODY') AND  STATUS!='VALID' ORDER BY 4)   LOOP 

               BEGIN 
                      IF cur_rec.object_type='PACKAGE '   THEN 
                            EXECUTE  IMMEDIATE  'ALTER '||cur_rec.object_type||' 
                                   "'||cur_rec.owner||'"."'||cur_rec.object_name||'" COMPILE'; 
                      ElSE 
                             EXECUTE IMMEDIATE'ALTER PACKAGE 
                                   "'||cur_rec.owner||'"."'||cur_rec.object_name||'" COMPILE BODY'; 
                     END IF; 
              EXCEPTION 
                      WHEN OTHERS THEN 
                                  DBMS_OUTPUT.put_line(cur_rec.object_type||' : '||cur_rec.owner||' : 
                                  '||cur_rec.object_name); 
              END; 
    END LOOP; 
END;

/

4、使用DBMS_UTILITY.compile_schema

使用这个包将会编译指定schema下的所有procedures, functions, packages, and triggers.
你可以在sqlplus 下使用它,如:
SQL>  EXEC DBMS_UTILITY.compile_schema(schema => ‘SCOTT’);

5、使用UTL_RECOMP
UTL_RECOMP包有两个存储过程:RECOMP_SERIAL 和  RECPMP_PARALLEL
从存储过程的名字可以看出一个是非并行,一个是并行方式.
使用并行方式会加快编译速度,包的定义如下:

PROCEDURE  RECOMP_SERIAL(
schema IN VARCHAR2 DEFAULT NULL,
flags IN PLS_INTEGER DEFAULT 0);

PROCEDURE RECOMP_PARALLEL
threads IN PLS_INTEGER DEFAULT NULL,
schema IN VARCHAR2 DEFAULT NULL,
flags IN PLS_INTEGER DEFAULT 0);

参数使用方法:
schema
- 想编译的模式,如果为NULL,将编译数据库的所有无效对象.
threads
- 并行度,如果为NULL,会使用参数job_queue_processes的值.
通常threads的值最好和CPU的数量想匹配,以发挥并行的最大优势.
flags
ORACLE内部使用的诊断测试参数.
如:

-- Schema level.EXEC UTL_RECOMP.recomp_serial('SCOTT'); 
SQL> EXEC UTL_RECOMP.recomp_parallel(4,'SCOTT'); 
 -- Database level.EXEC UTL_RECOMP.recomp_serial(); 
SQL> EXEC UTL_RECOMP.recomp_parallel(4); 
 -- Using job_queue_processes value.EXEC UTL_RECOMP.recomp_parallel(); 
SQL>  EXEC UTL_RECOMP.recomp_parallel(NULL,'SCOTT');

UTL_RECOMP包的一些使用限制

(1).并行执行使用的是job队列.当运行并行编译的时候所有job都会被diable直到编译完成.
(2).包必须在sqlplus中以sys用户或者有sysdba权限的用户运行.
(3).UTL_RECOMP依赖于DBMS_STANDARD,DBMS_JOB,DBMS_RANDOM
(4).如果在运行这个包的时候执行DDL语句可能会导致死锁.

6、utlrp.sql 和 utlprp.sql
utlrp和utlprp脚本可以用来重编译数据库的所有无效对象.通常我们会在Oracle的升级指导中看到这个脚本,Oracle强烈推荐在migration/upgrade/downgrade之后,通过运行此脚本编译失效对象.

脚本位于$ORACLE_HOME/rdbms/admin目录.你可以看到utlrp.sql只是调用utlprp.sql,  utlrp.sql在调用utlprp.sql的时候会传递给它一个参数,默认为0,这个参数其实就是并行度,其实utlprp.sql调用的是utl_recomp.recomp_parallel:


- 基于CPU_COUNT参数设置并行度.
1 - 以串行方式编译对象,一次编译一个.
N - 以N个并行度进行编译.
脚本需要以sys用户或者有sysdba权限的用户来运行,并且当时数据库中最好不要有活动事物或DDL操作,否则极容易导致死锁的出现(这是很容易理解的)

自动编译可能成功也可能失败。
时间: 2024-11-07 15:57:52

重新编译数据库中的失效对象的相关文章

批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor

原文:批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor 批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor2.1.11 之前写过一篇文章,使用redgate公司的SQL PROMPT工具,但是不太方便 SQLPROMPT5.3对各种加密对象的解密测试 SQL2005解密已经被加密的存储过程 昨天ahdung 童鞋介绍了这个工具给我,非常感谢他 dbForge SQL Decryptor这个工具的软件公司是dev

Java从数据库中读取Blob对象图片并显示的方法_java

本文实例讲述了Java从数据库中读取Blob对象图片并显示的方法.分享给大家供大家参考.具体实现方法如下: 第一种方法: 大致方法就是,从数据库中读出Blob的流来,写到页面中去: 复制代码 代码如下: Connection conn = DBManager.getConnection();   String sql = "SELECT picture FROM teacher WHERE id=1";   PreparedStatement ps = null;   ResultSe

如何显示数据库中以 OLE 对象方式存储的 JPEG 图片

对象|数据|数据库|显示 在 ASP 中, 我们经常需要在 Web 页面上显示以二进制方式保存在数据库中的图片. 一般的图片显示没有什么问题, 因为这方面的文章已经很多了, 我就不再阐述. 但有时候数据库中的图片是通过其他办公软件输入的, 或者通过其他方式, 比如在 Access 中直接添加. 这时, 图片以 OLE 对象的方式保存在数据库中, 在图片真实内容的前面, 还保存了一些其他的信息, 比如图片的路径和文件名,等等. 如果我们还用一般的输出方式的话, 就会出错, 导致图片不能显示. 幸好

oracle数据库中的大对象1——永久性的

整理自丁俊老师plsql文档: 1.基本介绍 oracle和pl/sql都支持lob(large object)类型,用来存储大数量数据,如图像文件,声音文件等.oracle 10g r1 支持最大8 到128万一字节的数据存储,依赖于你的数据库的 block size. 在pl/sql中,可以声明的lob的类型变量如下: BFILE :二进制文件,存储在数据库外的操作系统文件,只读的.把此文件当二进制处理. BLOB:二进制大对象,存储在数据库里的大对象,一般是图像声音等文件. CLOB: 字

oracle数据库中的大对象2—— temporary lobs

              到目前为止,我们讨论的都是持久化到数据库中的lob数据,但是实际应用中,我们有时候并不需要将数据持久化到数据库中,那么就需要用到Temporary lob(临时lob),它就像局部变量一样,并不持久化到数据库中.我们将讨论temporary lob和用dbms_lob包来操作它们. Oracle 8i之后支持创建,解除,访问,更新Temporary lob通过oci(oracle call interface)和dbms_lob包.临时lob的生命周期是在创建它的se

重新编译PLSQL中的无效对象或者指定的对象 的方法_oracle

Oracle   Tips,   Tricks   &   Scripts      1.   Topic:   Compiling   Invalid   Objects:      Oracle8i   and   Oracle9i   provides   a   script   called   utlrp.sql   located   in   $ORACLE_HOME/rdbms/admin   which   can   be   used   anytime   to   r

SQL Server数据库中tempdb性能分析

SQL Server有四个重要的系统级数据库:master,model,msdb,tempdb. 1.SQL Server系统数据库介绍 SQL Server有四个重要的系统级数据库:master,model,msdb,tempdb. master:记录SQL Server系统的所有系统级信息,包括实例范围的元数据,端点,链接服务器和系统配置设置,还记录其他数据库是否存在以及这些数据问文件的位置等等.如果master不可用,数据库将不能启动. model:用在SQL Server 实例上创建的所

深入解析Java的Hibernate框架中的持久对象_java

一.持久对象生命周期应用程序在使用Hibernate框架后,创建的持久对象会经历一整套生命周期来完成数据库的操作,其中主要的三个状态分别是瞬态(Transient).持久化(Persistent).脱管(detached).这三种状态的转换是能够在应用程序中控制的,如下图: 为了能清楚的了解这几种状态,这里使用一个实例来查看下这几种状态下对象的不同,下面状态内的代码,具体步骤如下: (1)创建Hibernate_session程序集,并添加像相应的jar包: (2)配置Hibernate,添加相

如何使用Visual Studio 2010在数据库中生成随机测试数据_MsSql

测试在项目中是很重要的一个环节,在Visual Studio 2010中,在测试方面已经有很好的支持了,比如有单元测试,负载测试等等.在数据测试的方面,Visual Studio 2010,还支持对数据库进行多种测试,其中一个很好用的功能是能为开发者在测试阶段,大量方便地为数据库生成随机的数据,而且还可以自己指定生成数据的规则,十分方便,这就让在测试过程中,开发者能有更充足的数据样本对项目进行测试.本文则介绍其中的Data Generation数据生成器的使用方法. 1 创建SQL Server