在11g之前,Oracle判断依赖性只达到了对象级,也就是说存储过程访问的对象一旦发生了变化,那么Oracle就会将存储过程置为INVALID状态,这样就导致了表结构变动后如果没有重新编译,那存储过程执行出错。尽管有的时候修改往往和关联的存储过程没有关系,但是Oracle并不对这种情况进行判断,这样会造成很多不需要重新编译的存储过程也被置于INVALID状态。
10g测试:
create table ptest1(vl_1 number);
create or replace procedure pp_test
is
vv_data varchar2(40);
BEGIN
update ptest1 set vl_1=1;
commit;
END pp_test;
SQL> select status from dba_objects where object_name=upper('pp_test');
STATUS
-------
VALID
SQL>
SQL> -- Add/modify columns
SQL> alter table PTEST1 add VL_2 number;
Table altered
SQL> select status from dba_objects where object_name=upper('pp_test');
STATUS
-------
INVALID
由上例可以看到,增加了的字段其实和存储过程没有关系,但是存储过程还是失效了。
11g测试:
create table ptest1(vl_1 number);
create or replace procedure pp_test
is
vv_data varchar2(40);
BEGIN
update ptest1 set vl_1=1;
commit;
END pp_test;
SQL> select status from dba_objects where object_name=upper('pp_test');
STATUS
-------
VALID
alter table PTEST1 add VL_2 number;
SQL> alter table PTEST1 add VL_2 number;
Table altered
SQL> select status from dba_objects where object_name=upper('pp_test');
STATUS
-------
VALID
由上例可以看到,虽然增加了的字段,但是因为和存储过程没有关系,但是存储过程还是有效的。
字段级依赖性的信息存储在dependency$的d_attrs列中。具体算法我也不想深究了,据说和物化视图的很相似。