The number of invalid objects does not 'randomly' increase or decrease.
Objects go invalid for a number of reasons. Grants for example (change grants, things go invalid). Cascading invalidations - procedure P goes invalid, so goes everything that references P.
utlrp issues an alter thing COMPILE, it explicitly compiles the code (that is what it is designed to do). I would suggest...... Just leaving them be. They will recompile all by themselves as needed, you need take no action whatsoever. And the last ddl time will not be touched, implicit compiles do not touch it.
ops$tkyte%ORA10GR2> create user a identified by a;
User created.
ops$tkyte%ORA10GR2> grant create session, create procedure to a;
Grant succeeded.
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> grant select on scott.emp to a;
Grant succeeded.
ops$tkyte%ORA10GR2> grant select on scott.emp to public;
Grant succeeded.
ops$tkyte%ORA10GR2> grant select any table to a;
Grant succeeded.
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> connect a/a
Connected.
a%ORA10GR2> create or replace procedure p
2 as
3 begin
4 for x in (select * from scott.emp)
5 loop
6 null;
7 end loop;
8 end;
9 /
Procedure created.
a%ORA10GR2>
a%ORA10GR2> column object_name format a8
a%ORA10GR2> select object_name, status,
2 to_char(last_ddl_time,'dd-mon-yyyy hh24:mi:ss') lddl_time,
3 to_char(sysdate,'dd-mon-yyyy hh24:mi:ss') now
4 from user_objects;
OBJECT_N STATUS LDDL_TIME NOW
-------- ------- -------------------- --------------------
P VALID 24-jun-2008 08:07:14 24-jun-2008 08:07:14
a%ORA10GR2> connect /
Connected.
ops$tkyte%ORA10GR2> exec dbms_lock.sleep(5)
PL/SQL procedure successfully completed.
ops$tkyte%ORA10GR2> revoke select any table from a;
Revoke succeeded.
ops$tkyte%ORA10GR2> connect a/a
Connected.
a%ORA10GR2>
a%ORA10GR2> column object_name format a8
a%ORA10GR2> select object_name, status,
2 to_char(last_ddl_time,'dd-mon-yyyy hh24:mi:ss') lddl_time,
3 to_char(sysdate,'dd-mon-yyyy hh24:mi:ss') now
4 from user_objects;
OBJECT_N STATUS LDDL_TIME NOW
-------- ------- -------------------- --------------------
P INVALID 24-jun-2008 08:07:14 24-jun-2008 08:07:19
<b>Note the revoke invalidated this procedure, we do not remember WHAT GRANT we used when compiling, all we know is "we were able to access scott.emp". When you revoke select any table from A, that tells us "any of the procedures that access tables might be wrong now, we need to invalidate them"</b>
a%ORA10GR2> exec p
PL/SQL procedure successfully completed.
a%ORA10GR2> select object_name, status,
2 to_char(last_ddl_time,'dd-mon-yyyy hh24:mi:ss') lddl_time,
3 to_char(sysdate,'dd-mon-yyyy hh24:mi:ss') now
4 from user_objects;
OBJECT_N STATUS LDDL_TIME NOW
-------- ------- -------------------- --------------------
P VALID 24-jun-2008 08:07:14 24-jun-2008 08:07:19
<b>and note that the last ddl time did not budge, it compiled itself safely</b>
a%ORA10GR2>
a%ORA10GR2> connect /
Connected.
ops$tkyte%ORA10GR2> revoke select on scott.emp from public;
Revoke succeeded.
ops$tkyte%ORA10GR2> connect a/a
Connected.
a%ORA10GR2>
a%ORA10GR2> column object_name format a8
a%ORA10GR2> select object_name, status,
2 to_char(last_ddl_time,'dd-mon-yyyy hh24:mi:ss') lddl_time,
3 to_char(sysdate,'dd-mon-yyyy hh24:mi:ss') now
4 from user_objects;
OBJECT_N STATUS LDDL_TIME NOW
-------- ------- -------------------- --------------------
P INVALID 24-jun-2008 08:07:14 24-jun-2008 08:07:20
<b>again, P went invalid - even though A still has select on emp. Anything that selected from emp in our database would go invalid if select were revoked from public like that - because anything could have relied on that privilege...</b>
a%ORA10GR2> alter procedure p compile;
Procedure altered.
a%ORA10GR2> select object_name, status,
2 to_char(last_ddl_time,'dd-mon-yyyy hh24:mi:ss') lddl_time,
3 to_char(sysdate,'dd-mon-yyyy hh24:mi:ss') now
4 from user_objects;
OBJECT_N STATUS LDDL_TIME NOW
-------- ------- -------------------- --------------------
P VALID 24-jun-2008 08:07:20 24-jun-2008 08:07:20
<b>when we utlrp (which compiles using alter compile), it will necessarily update the last ddl time, since we explicitly did ddl on it!</b>