LAST_DDL_TIME vs TIMESTAMP nas views DBA / ALL / USER_OBJECTS. Tem diferença?
Não é raro muita gente confundir essas duas colunas existentes nas views de dicionário de dados DBA/ALL/USER_OBJECTS. Afinal, qual é a diferença entre elas? Quando é que a informação de data e horário de uma é atualizada e da outra não? Pois bem, vamos então a alguns exemplos práticos de forma a demonstrar essa diferença.
C:\>sqlplus scott/tiger
SQL*Plus: Release 10.2.0.1.0 - Production on Seg Mai 2 11:49:38 2011
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Conectado a:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> desc user_objects
Nome Nulo? Tipo
----------------------------- -------- ----------------------------
OBJECT_NAME VARCHAR2(128)
SUBOBJECT_NAME VARCHAR2(30)
OBJECT_ID NUMBER
DATA_OBJECT_ID NUMBER
OBJECT_TYPE VARCHAR2(19)
CREATED DATE
LAST_DDL_TIME DATE
TIMESTAMP VARCHAR2(19)
STATUS VARCHAR2(7)
TEMPORARY VARCHAR2(1)
GENERATED VARCHAR2(1)
SECONDARY VARCHAR2(1)
Primeiramente, podemos perceber que LAST_DDL_TIME é uma coluna do tipo DATE e TIMESTAMP, por incrível que pareça, é um VARCHAR2(19). Irei criar abaixo uma tabela de exemplo e realizar algumas operações nela.
SQL> create table t1 (id number);
Tabela criada.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='T1';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
T1 02/05/2011 11:59:00 02/05/2011 11:59:00 2011-05-02:11:59:00
Acima, podemos perceber que tanto a coluna CREATED, como LAST_DDL_TIME e TIMESTAMP possuem a mesma informação de data e horário. O que acontece se modificarmos a estrutura da tabela?
SQL> alter table t1 modify id number(10,2);
Tabela alterada.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='T1';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
T1 02/05/2011 11:59:00 02/05/2011 12:00:00 2011-05-02:12:00:00
Ambas as colunas LAST_DDL_TIME e TIMESTAMP tiveram suas informações atualizadas. Mas, o que acontece agora se eu simplesmente conceder alguns privilégios (SELECT, por exemplo) para algum outro usuário?
SQL> grant select on t1 to adam;
Concessão bem-sucedida.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='T1';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
T1 02/05/2011 11:59:00 02/05/2011 12:02:00 2011-05-02:12:00:00
Podemos perceber que somente a coluna LAST_DDL_TIME teve sua informação atualizada, apesar do comando GRANT ser um comando DCL (Data Control Language). No mais, podemos perceber abaixo que o comando REVOKE terá o mesmo efeito apenas na coluna LAST_DDL_TIME.
SQL> revoke select on t1 from adam;
Revogação bem-sucedida.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='T1';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
T1 02/05/2011 11:59:00 02/05/2011 12:04:00 2011-05-02:12:00:00
Existem mais comandos que afetam apenas a coluna LAST_DDL_TIME e não a coluna TIMESTAMP? Sim.
SQL> alter table t1 move;
Tabela alterada.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='T1';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
T1 02/05/2011 11:59:00 02/05/2011 12:06:00 2011-05-02:12:00:00
SQL> insert into t1 values (1);
1 linha criada.
SQL> commit;
Commit concluído.
SQL> truncate table t1;
Tabela truncada.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='T1';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
T1 02/05/2011 11:59:00 02/05/2011 12:08:00 2011-05-02:12:00:00
Perceberam que o comando ALTER TABLE MOVE… e TRUNCATE TABLE… atualizaram apenas a coluna LAST_DDL_TIME? Irei agora realizar o mesmo teste só que agora com uma FUNCTION. (obs: Poderia também ser uma STORED PROCEDURE ou uma TRIGGER).
SQL> create or replace function data_atual return date is
2 data date;
3 begin
4 select sysdate into data from dual;
5 return data;
6 end;
7 /
Função criada.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='DATA_ATUAL';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
DATA_ATUAL 02/05/2011 12:59:00 02/05/2011 12:59:00 2011-05-02:12:59:00
Acima, podemos perceber que tanto a coluna CREATED, como LAST_DDL_TIME e TIMESTAMP possuem a mesma informação de data e horário. O que acontece se modificarmos o código PL/SQL da função?
SQL> create or replace function data_atual return date is
2 data date;
3 begin
4 select sysdate+1 into data from dual;
5 return data;
6 end;
7 /
Função criada.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='DATA_ATUAL';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
DATA_ATUAL 02/05/2011 12:59:00 02/05/2011 13:00:00 2011-05-02:13:00:00
Ambas as colunas LAST_DDL_TIME e TIMESTAMP tiveram suas informações atualizadas. Mas, o que acontece se eu simplesmente conceder alguns privilégios (EXECUTE, por exemplo) para algum outro usuário?
SQL> grant execute on data_atual to adam;
Concessão bem-sucedida.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='DATA_ATUAL';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
DATA_ATUAL 02/05/2011 12:59:00 02/05/2011 13:02:00 2011-05-02:13:00:00
Podemos perceber que somente a coluna LAST_DDL_TIME teve sua informação atualizada. Vale a penas salientar que o comando REVOKE terá o mesmo efeito. O que acontece agora se apenas compilarmos a função sem qualquer alteração em seu código fonte?
SQL> alter function data_atual compile;
Função alterada.
SQL> select object_name,created,last_ddl_time,timestamp
2 from user_objects
3 where object_name='DATA_ATUAL';
OBJECT_NAME CREATED LAST_DDL_TIME TIMESTAMP
--------------- ------------------- ------------------- -------------------
DATA_ATUAL 02/05/2011 12:59:00 02/05/2011 13:04:00 2011-05-02:13:00:00
Novamente podemos perceber que somente a coluna LAST_DDL_TIME teve sua informação atualizada.
Em resumo:
A coluna LAST_DDL_TIME armazena a informação de data e horário sobre a última vez quando o objeto foi modificado por uma instrução DDL, incluindo alguns comandos que envolvam modificações no nível de extensões (extents) do segmento. Vale a pena salientar que essa modificação também vale para comandos DCL como (GRANT e REVOKE) que foram lançados sobre o objeto. Isso também vale para os objetos PL/SQL como functions, stored procedures, triggers, entre outros, incluindo-se o comando COMPILE executado sobre o mesmo.
Por fim, a coluna TIMESTAMP armazena a informação de data e horário sobre a última vez quando o objeto foi modificado, excluindo-se qualquer operação DCL (GRANT, REVOKE) e excluindo-se também alguns comandos DDL que afetem o objeto no nível de extensões (extents) do segmento. No caso de objetos PL/SQL, exclui-se também o comando COMPILE.
Portanto, se quiser saber realmente quando houve alguma modificação estrutural na tabela ou alguma modificação no código de um de objeto PL/SQL, confie na coluna TIMESTAMP.