oracle重新编译失效对象的几种方法
手工重编译
查看失效对象
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);
原文:
https://oracle-base.com/articles/misc/recompiling-invalid-schema-objects