在数据库中,会存在一些无效的对象,导致这种现象的发生原因很多,其中最常见的就是数据库升级(例如修改了表的结构),迁移而引起。
有两种编译无效对象的方式:
1 使用alter **** compile 语句进行编译
2 以SYSDBA用户,执行ORACLE_HOME/rdbms/admin/utlrp.sql 脚本
3 用DBMS_UTILITY包来进行编译.
具体使用哪种,根据实际情况选择。
查询无效对象SQL:
SELECT COUNT (*)
FROM user_objects
WHERE object_type IN (’PROCEDURE’,’FUNCTION’,’TRIGGER’,’VIEW’,’PACKAGE’)
AND status = ’INVALID’.
在SQL*plus中利用中间脚本编译
编写SQL*Plus脚本,它可以帮组你扫描非法的脚本并尝试重新编译它们:
建立脚本reCompile.sql
SET feedback OFF
SET heading OFF
SET linesize 1000
SET pagesize 0
SET pause OFF
SET trimspool ON
SET verify OFF
spool tmp.sql.
SELECT ’alter ’||object_type||’ ’||owner||’.’||object_name||’ compile.’
FROM all_objects
WHERE status = ’INVALID’
AND object_type in
(’FUNCTION’,’JAVA SOURCE’,’JAVA CLASS’,’PROCEDURE’,’PACKAGE’,’TRIGGER’).
SELECT ’alter package ’||owner||’.’||object_name||’ compile body.’
FROM all_objects
WHERE status = ’INVALID’
AND object_type = ’PACKAGE BODY’.
spool OFF.
@tmp.sql
在SQL*Plus中
@reCompile.sql
当你运行的时候,这个脚本将会创建第二个脚本,这个脚本叫做Tmp.sql。它发布所有的ALTER命令然后运行这个脚本。
编写PL/SQL利用游标编译
在上面的方法中,只能知道某某编译失败,不清楚失败原因,可以用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.