手工重编译

查看失效对象

COLUMN object_name FORMAT A30
SELECT owner,
       object_type,
       object_name,
       status
FROM   dba_objects
WHERE  status = 'INVALID'
ORDER BY owner, object_type, object_name;

 

少量直接alter, 注意包体需要加body

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

 

或者使用DBMS_DDL.alter_compile包 (不能重新编译view)

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

大量写匿名块

SET SERVEROUTPUT ON SIZE 1000000
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;
/

 

UTL_RECOMP

UTL_RECOMP包中包含两个用于重新编译无效对象的过程。 顾名思义,RECOMP_SERIAL过程一次重新编译所有无效对象,而RECOMP_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 - 要重新编译其无效对象的schema。 如果为NULL,则重新编译数据库中的所有无效对象。
  • threads - 并行操作中使用的线程数。 如果为NULL,则使用“job_queue_processes”参数的值。 匹配可用CPU的数量通常是此值的良好起点。
  • flags - 仅用于内部诊断和测试。

以下示例显示了如何使用这些过程。

-- Schema level.
EXEC UTL_RECOMP.recomp_serial('SCOTT');
EXEC UTL_RECOMP.recomp_parallel(4, 'SCOTT');

-- Database level.
EXEC UTL_RECOMP.recomp_serial();
EXEC UTL_RECOMP.recomp_parallel(4);

-- Using job_queue_processes value.
EXEC UTL_RECOMP.recomp_parallel();
EXEC UTL_RECOMP.recomp_parallel(NULL, 'SCOTT');

 

使用此软件包有许多限制,包括:

  • 使用作业队列执行并行执行。 在操作完成之前,所有现有作业都标记为已禁用。
  • 该程序包必须作为SYS用户从SQL * Plus或具有SYSDBA的其他用户运行。
  • 该程序包期望STANDARD,DBMS_STANDARD,DBMS_JOB和DBMS_RANDOM存在且有效。
    在此程序包的同时运行DDL操作可能会导致死锁。

utlrp.sql and utlprp.sql

Oracle提供了utlrp.sql和utlprp.sql脚本来重新编译数据库中的所有无效对象。 它们通常在主要数据库更改(如升级或修补程序)之后运行。 它们位于$ORACLE_HOME/rdbms/admin目录中,并在UTL_RECOMP包中提供包装器。 utlrp.sql脚本只是使用命令行参数“0”调用utlprp.sql脚本。 utlprp.sql接受一个整数参数,该参数指示并行度,如下所示。

  • 0 - 并行级别基于CPU_COUNT参数派生。
  • 1 - 重新编译是串行运行的,一次一个对象。
  • N - 重新编译与“N”个线程并行运行。
    必须以SYS用户或具有SYSDBA的其他用户身份运行这两个脚本才能正常工作。

DBMS_UTILITY.compile_schema

DBMS_UTILITY包中的COMPILE_SCHEMA过程编译指定模式中的所有过程,函数,包和触发器。 下面的示例显示了如何从SQL * Plus调用它。

EXEC DBMS_UTILITY.compile_schema(schema => 'SCOTT', compile_all => false);
  • 1

原文:
https://oracle-base.com/articles/misc/recompiling-invalid-schema-objects

 posted on 2020-02-27 14:13  xibuhaohao  阅读(2651)  评论(0编辑  收藏  举报