martes, 13 de agosto de 2019

Cómo conocer el último registro ingresado en una tabla en Oracle, sin tener un campo TIMESTAMP?

A ver, una forma simple de como saber el último registro que ha sido insertado en una tabla.
Para ello vamos a crear una tabla de pruebas y vamos a ingresar algunos registros. Para que nos sirva de validación visual, crearemos una columna tipo DATE y otra con un valor de una secuencia. La tercera columna es relleno.

Connected.
SQL> drop table t;
drop table t
           *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> create table t ( fecha date, secuencia number, string varchar2(50));

Table created.

SQL> create sequence n_consecutivo;

Sequence created.

SQL> insert into t values ( sysdate, n_consecutivo.nextval, sysdate||n_consecutivo.nextval);

1 row created.

SQL> insert into t values ( sysdate, n_consecutivo.nextval, sysdate||n_consecutivo.nextval);

1 row created.

SQL> insert into t values ( sysdate, n_consecutivo.nextval, sysdate||n_consecutivo.nextval);

1 row created.

SQL> insert into t values ( sysdate, n_consecutivo.nextval, sysdate||n_consecutivo.nextval);

1 row created.

SQL> insert into t values ( sysdate, n_consecutivo.nextval, sysdate||n_consecutivo.nextval);

1 row created.

SQL> commit;

Commit complete.

Veamos el contenido de la tabla.
SQL> select * from t;

FECHA                SECUENCIA STRING
------------------- ---------- -----------------------
13-08-2019 14:58:10          1 13-08-2019 14:58:101
13-08-2019 14:58:15          2 13-08-2019 14:58:152
13-08-2019 14:58:17          3 13-08-2019 14:58:173
13-08-2019 14:58:18          4 13-08-2019 14:58:184
13-08-2019 14:58:20          5 13-08-2019 14:58:205

El método utilizando el rownum, no nos sirve de nada.

SQL> select * from t where rownum = ( select max(rownum) from t);

no rows selected

SQL> select max(rownum) from t;

MAX(ROWNUM)
-----------
          5

SQL> select * from t where rownum = 5;

no rows selected

Las seudocolumnas con información de SCN, tampoco nos sirven, porque van variando según el último cambio generado en alguno de los registros de la tabla.

SQL> select ora_rowscn,scn_to_timestamp(ora_rowscn),fecha, secuencia, string from t;

ORA_ROWSCN SCN_TO_TIMESTAMP(ORA_ROWSCN)        FECHA                SECUENCIA STRING
---------- ----------------------------------- ------------------- ---------- ---------------------
3.9824E+10 13-AUG-19 02.58.19.000000000 PM     13-08-2019 14:58:10          1 13-08-2019 14:58:101
3.9824E+10 13-AUG-19 02.58.19.000000000 PM     13-08-2019 14:58:15          2 13-08-2019 14:58:152
3.9824E+10 13-AUG-19 02.58.19.000000000 PM     13-08-2019 14:58:17          3 13-08-2019 14:58:173
3.9824E+10 13-AUG-19 02.58.19.000000000 PM     13-08-2019 14:58:18          4 13-08-2019 14:58:184
3.9824E+10 13-AUG-19 02.58.19.000000000 PM     13-08-2019 14:58:20          5 13-08-2019 14:58:205

SQL> insert into t values ( sysdate, n_consecutivo.nextval, sysdate||n_consecutivo.nextval);

1 row created.

SQL> commit;

Commit complete.

SQL> select ora_rowscn,scn_to_timestamp(ora_rowscn),fecha, secuencia, string from t;

ORA_ROWSCN SCN_TO_TIMESTAMP(ORA_ROWSCN)         FECHA                SECUENCIA STRING
---------- ------------------------------------ ------------------- ---------- ---------------------
3.9824E+10 13-AUG-19 03.02.13.000000000 PM      13-08-2019 14:58:10          1 13-08-2019 14:58:101
3.9824E+10 13-AUG-19 03.02.13.000000000 PM      13-08-2019 14:58:15          2 13-08-2019 14:58:152
3.9824E+10 13-AUG-19 03.02.13.000000000 PM      13-08-2019 14:58:17          3 13-08-2019 14:58:173
3.9824E+10 13-AUG-19 03.02.13.000000000 PM      13-08-2019 14:58:18          4 13-08-2019 14:58:184
3.9824E+10 13-AUG-19 03.02.13.000000000 PM      13-08-2019 14:58:20          5 13-08-2019 14:58:205
3.9824E+10 13-AUG-19 03.02.13.000000000 PM      13-08-2019 15:02:13          6 13-08-2019 15:02:136

6 rows selected.

Pero si utilizamos el ROWID, ahí podemos obtener la información que andamos buscando.
SQL> select * from t where rowid in(select max(rowid) from t);

FECHA                SECUENCIA STRING
------------------- ---------- ---------------------
13-08-2019 15:02:13          6 13-08-2019 15:02:136

SQL> insert into t values ( sysdate, n_consecutivo.nextval, sysdate||n_consecutivo.nextval);

1 row created.

SQL> commit;

Commit complete.

SQL> select ora_rowscn,scn_to_timestamp(ora_rowscn),fecha, secuencia, string from t;

ORA_ROWSCN SCN_TO_TIMESTAMP(ORA_ROWSCN)          FECHA                SECUENCIA STRING
---------- ------------------------------------- ------------------- ---------- ---------------------
3.9824E+10 13-AUG-19 03.04.01.000000000 PM       13-08-2019 14:58:10          1 13-08-2019 14:58:101
3.9824E+10 13-AUG-19 03.04.01.000000000 PM       13-08-2019 14:58:15          2 13-08-2019 14:58:152
3.9824E+10 13-AUG-19 03.04.01.000000000 PM       13-08-2019 14:58:17          3 13-08-2019 14:58:173
3.9824E+10 13-AUG-19 03.04.01.000000000 PM       13-08-2019 14:58:18          4 13-08-2019 14:58:184
3.9824E+10 13-AUG-19 03.04.01.000000000 PM       13-08-2019 14:58:20          5 13-08-2019 14:58:205
3.9824E+10 13-AUG-19 03.04.01.000000000 PM       13-08-2019 15:02:13          6 13-08-2019 15:02:136
3.9824E+10 13-AUG-19 03.04.01.000000000 PM       13-08-2019 15:04:02          7 13-08-2019 15:04:027

7 rows selected.

SQL>  select * from t where rowid in(select max(rowid) from t);

FECHA                SECUENCIA STRING
------------------- ---------- ---------------------
13-08-2019 15:04:02          7 13-08-2019 15:04:027

SQL>

SQL> select * from t order by rowid;

FECHA                SECUENCIA STRING
------------------- ---------- ---------------------
13-08-2019 14:58:10          1 13-08-2019 14:58:101
13-08-2019 14:58:15          2 13-08-2019 14:58:152
13-08-2019 14:58:17          3 13-08-2019 14:58:173
13-08-2019 14:58:18          4 13-08-2019 14:58:184
13-08-2019 14:58:20          5 13-08-2019 14:58:205
13-08-2019 15:02:13          6 13-08-2019 15:02:136
13-08-2019 15:04:02          7 13-08-2019 15:04:027

7 rows selected.

Que pasa si actualizamos un registro 'X' en la tabla.?
SQL> update t
  2  set fecha=sysdate
  3  where secuencia=2;

1 row updated.

SQL> commit;

Commit complete.

SQL> select ora_rowscn,scn_to_timestamp(ora_rowscn),fecha, secuencia, string from t;

ORA_ROWSCN SCN_TO_TIMESTAMP(ORA_ROWSCN)           FECHA                SECUENCIA STRING
---------- -------------------------------------- ------------------- ---------- --------------------
3.9824E+10 13-AUG-19 03.16.07.000000000 PM        13-08-2019 14:58:10          1 13-08-2019 14:58:101
3.9824E+10 13-AUG-19 03.16.07.000000000 PM        13-08-2019 15:16:08          2 13-08-2019 14:58:152
3.9824E+10 13-AUG-19 03.16.07.000000000 PM        13-08-2019 14:58:17          3 13-08-2019 14:58:173
3.9824E+10 13-AUG-19 03.16.07.000000000 PM        13-08-2019 14:58:18          4 13-08-2019 14:58:184
3.9824E+10 13-AUG-19 03.16.07.000000000 PM        13-08-2019 14:58:20          5 13-08-2019 14:58:205
3.9824E+10 13-AUG-19 03.16.07.000000000 PM        13-08-2019 15:02:13          6 13-08-2019 15:02:136
3.9824E+10 13-AUG-19 03.16.07.000000000 PM        13-08-2019 15:04:02          7 13-08-2019 15:04:027

7 rows selected.

Con la actualización no tenemos ningún problema.

SQL> select * from t order by rowid;

FECHA                SECUENCIA STRING
------------------- ---------- --------------------
13-08-2019 14:58:10          1 13-08-2019 14:58:101
13-08-2019 15:16:08          2 13-08-2019 14:58:152
13-08-2019 14:58:17          3 13-08-2019 14:58:173
13-08-2019 14:58:18          4 13-08-2019 14:58:184
13-08-2019 14:58:20          5 13-08-2019 14:58:205
13-08-2019 15:02:13          6 13-08-2019 15:02:136
13-08-2019 15:04:02          7 13-08-2019 15:04:027

7 rows selected.

SQL> select * from t where rowid in(select max(rowid) from t);

FECHA                SECUENCIA STRING
------------------- ---------- --------------------
13-08-2019 15:04:02          7 13-08-2019 15:04:027

SQL>

1 comentario:

  1. Such a nice article. This is a very valuable thing you shared. good stuff!! Keep it up. please keep sharing content like this. I'll wait. kubota mu4501

    ResponderEliminar

Te agradezco tus comentarios. Te esperamos de vuelta.

Todos los Sábados a las 8:00PM

Optimismo para una vida Mejor

Optimismo para una vida Mejor
Noticias buenas que comentar