以前一直认为修改、删除对象和回收权限才会导致存储过程的状态变为INVALID,这两天在读TOM的书时突然想到,新建对象也可能导致存储过程的状态发生变化。
测试的例子很简单:
SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
2 BEGIN
3 FOR I IN (SELECT * FROM DUAL) LOOP
4 NULL;
5 END LOOP;
6 END;
7 /
过程已创建。
SQL> COL OBJECT_NAME FORMAT A30
SQL> SELECT OBJECT_NAME, STATUS FROM USER_OBJECTS WHERE OBJECT_NAME = 'P_TEST';
OBJECT_NAME STATUS
------------------------------ -------
P_TEST VALID
SQL> CREATE SYNONYM DUAL FOR T;
同义词已创建。
SQL> SELECT OBJECT_NAME, STATUS FROM USER_OBJECTS WHERE OBJECT_NAME = 'P_TEST';
OBJECT_NAME STATUS
------------------------------ -------
P_TEST INVALID
导致过程状态变为INVALID的原因是Oracle判断对象的顺序:Oracle首先寻找当前用户下的对象,然后才是PUBLIC同义词。因此,当前用户新建了一个与过程中使用的PUBLIC同义词同名的对象,导致了Oracle过程访问的对象发生了变化,于是过程的状态变成了INVALID。
因此,建立对象时也应当小心,应当尽量避免创建与PUBLIC同义词同名的对象。