Pular para o conteúdo

Qual a diferença entre as colunas LAST_DDL_TIME e TIMESTAMP nas views de dicionário de dados DBA/ALL/USER_OBJECTS?

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.

Eduardo Legatti

Eduardo Legatti

Eduardo Legatti é Analista de Sistemas e Administrador de banco de dados. É pós graduado em Gerência da Tecnologia da Informação, possui as certificações OCA 9i - OCP 9i/10g/11g – OCE SQL Expert, e vem trabalhando como DBA Oracle desde a versão 8.0.5. Se interessa particularmente em planejar estratégias de backup/recovery, performance tuning e projetos de bancos de dados (modelagem física e lógica) atuando como consultor. Como Oracle ACE, ele tem o hábito de disseminar seu conhecimento através de artigos, grupos de discussão (Oracle OTN Forums) e dedica-se a compartilhar informações de forma a motivar novos DBAs.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress