DBMS_UTILITY.COMPILE_SCHEMA(schema =&gt;'<schema_name>',compile_all =&gt; FALSE)不编译无效的包体</schema_name>

时间:2015-03-02 17:29:49

标签: oracle plsql

的召唤
BEGIN
    DBMS_UTILITY.COMPILE_SCHEMA(schema => '<SCHEMA_NAME>', compile_all => FALSE);
END;
/

不会编译无效的包体。有人知道原因吗?

(Oracle Database 11g企业版11.2.0.1.0版 - 生产版)

1 个答案:

答案 0 :(得分:7)

确实如此;至少在11.2.0.3中,所以我认为基础版本中可能存在错误。

如果我创建了一个无效的包,在这种情况下,因为它引用了一个不存在的表:

create package p42 as
  procedure test;
end p42;
/

PACKAGE P42 compiled

create package body p42 as
  procedure test is
    n number;
  begin
    select count(*) into n from t42;
  end test;
end p42;
/

PACKAGE BODY P42 compiled
Errors: check compiler log

然后检查状态和上次DDL时间:

select object_type, object_name, status, last_ddl_time
from user_objects where object_name = 'P42'
order by object_type, object_name;

OBJECT_TYPE         OBJECT_NAME          STATUS  LAST_DDL_TIME      
------------------- -------------------- ------- -------------------
PACKAGE             P42                  VALID   2015-03-02 17:39:42 
PACKAGE BODY        P42                  INVALID 2015-03-02 17:39:42 

然后重新编译架构并再次检查:

BEGIN
    DBMS_UTILITY.COMPILE_SCHEMA(schema => USER, compile_all => FALSE);
END;
/

anonymous block completed

select object_type, object_name, status, last_ddl_time
from user_objects where object_name = 'P42'
order by object_type, object_name;

OBJECT_TYPE         OBJECT_NAME          STATUS  LAST_DDL_TIME      
------------------- -------------------- ------- -------------------
PACKAGE             P42                  VALID   2015-03-02 17:39:42 
PACKAGE BODY        P42                  INVALID 2015-03-02 17:39:49 

..最后一次DDL时间已经改变,所以它被重新编译了。由于我没有解决潜在的问题,它仍然无效。我可以看到

select text from user_errors where name = 'P42';

TEXT                                                        
------------------------------------------------------------
PL/SQL: ORA-00942: table or view does not exist              
PL/SQL: SQL Statement ignored                                

或者如果您的'<SCHEMA_NAME>'不是您当前的用户,如果它仍然无效,则会all_errors

如果我创建缺失的表并再次编译模式:

create table t42 (id number);

Table t42 created.

BEGIN
    DBMS_UTILITY.COMPILE_SCHEMA(schema => USER, compile_all => FALSE);
END;
/

anonymous block completed

select object_type, object_name, status, last_ddl_time
from user_objects where object_name = 'P42'
order by object_type, object_name;

OBJECT_TYPE         OBJECT_NAME          STATUS  LAST_DDL_TIME      
------------------- -------------------- ------- -------------------
PACKAGE             P42                  VALID   2015-03-02 17:39:42 
PACKAGE BODY        P42                  VALID   2015-03-02 17:40:11 

...最后一次DDL时间再次发生变化,现状也是如此。如果我再次使用compile_all => FALSE标志进行编译,那么最后的DDL时间不会改变,因为它不会查看有效的包。