Oracle Flashback Transaction Query

De Dos Ideas.
Revisión del 18:10 26 ago 2009 de Admin (discusión | contribuciones)
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Saltar a: navegación, buscar

Flashback Transaction Query es una mejora introducida en [Oracle10g], de Oracle Flashback Query y utilizada frecuentemente en conjunto con Oracle Flashback Version Query. Flashback Transaction Query nos muestra información de la transacción adicional a la obtenida mediante Oracle Flashback Version Query , específicamente la sentencia de UNDO necesaria para volver la transacción atrás y que usuario de base de datos realizó la misma.

La vista que utilizaremos para ver esta información es FLASHBACK_TRANSACTION_QUERY, cuya columna xid coincide con el valor de la pseudo-columna versions_xid generada por Oracle Flashback Version Query.

Para poder consultar esta tabla el usuario debe tener el siguiente privilegio:

SELECT ANY TRANSACTION
sys@LAB10G> grant select any transaction to scott;
Concesión terminada correctamente.
scott@LAB10G> desc flashback_transaction_query
Nombre            Nulo Tipo
----------------- ---- --------------
XID                    RAW(8)
START_SCN              NUMBER
START_TIMESTAMP        DATE
COMMIT_SCN             NUMBER
COMMIT_TIMESTAMP       DATE
LOGON_USER             VARCHAR2(30)
UNDO_CHANGE#           NUMBER
OPERATION              VARCHAR2(32)
TABLE_NAME             VARCHAR2(256)
TABLE_OWNER            VARCHAR2(32)
ROW_ID                 VARCHAR2(19)
UNDO_SQL               VARCHAR2(4000)

Ejemplo

Vamos a utilizar las transacciones generadas por Flashback Version Query.

Modifico datos puntuales

scott@LAB10G> update emp_flash set ename='CARO' where empno=7369;
1 fila actualizada.
scott@LAB10G> commit;
Confirmación terminada.
scott@LAB10G> update emp_flash set ename='PEPE' where empno=7369;
1 fila actualizada.
scott@LAB10G> commit;
Confirmación terminada.
scott@LAB10G> SELECT
 2  versions_startscn, versions_endscn, versions_starttime, versions_endtime,
 3  versions_xid, versions_operation, ename
 4  FROM emp_flash
 5  VERSIONS BETWEEN TIMESTAMP
 6           TO_TIMESTAMP('24-08-2007 11:35', 'DD-MM-YYYY HH24:MI')
 7       AND TO_TIMESTAMP('24-08-2007 11:44', 'DD-MM-YYYY HH24:MI')
 8  WHERE empno = 7369;
startscn   endscn starttime         endtime           xid              o ENAME
-------- -------- ----------------- ----------------- ---------------- - ------
1032624          24/08/07 11:43:31                   04000300A4010000 U PEPE
1032516  1032624 24/08/07 11:38:18 24/08/07 11:43:31 010020009B010000 U CARO
                                                                       SMITH
scott@LAB10G> select
 2  undo_change#, operation, table_owner, table_name, row_id, undo_sql
 3  from flashback_transaction_query where xid = HEXTORAW('010020009B010000')
UNDO_CHANGE# OPERATION  TABLE_OWNE TABLE_NAME ROW_ID
------------ ---------- ---------- ---------- -------------------
UNDO_SQL
-------------------------------------------------------------------------------
 1 UPDATE     SCOTT      EMP_FLASH  AAANC8AAEAAAAGkAAO
update "SCOTT"."EMP_FLASH" set "ENAME" = 'SMITH' where ROWID ='AAANC8AAEAAAAGkAAO';
 2 BEGIN
scott@LAB10G> select
 2  undo_change#, operation, table_owner, table_name, row_id, undo_sql
 3  from flashback_transaction_query where xid = HEXTORAW('04000300A4010000');
UNDO_CHANGE# OPERATION  TABLE_OWNE TABLE_NAME ROW_ID
------------ ---------- ---------- ---------- -------------------
UNDO_SQL
-------------------------------------------------------------------------------
 1 UPDATE     SCOTT      EMP_FLASH  AAANC8AAEAAAAGkAAO

update "SCOTT"."EMP_FLASH" set "ENAME" = 'CARO' where ROWID ='AAANC8AAEAAAAGkAAO';

 2 BEGIN


Modifico muchos datos por sentencia

scott@LAB10G> update emp_flash set sal=sal+100 where deptno=10;
3 filas actualizadas.
scott@LAB10G> commit;
Confirmación terminada.
scott@LAB10G> SELECT
 2  versions_starttime, versions_endtime,
 3  versions_xid, versions_operation, empno, ename, sal
 4  FROM emp_flash
 5  VERSIONS BETWEEN TIMESTAMP
 6            TO_TIMESTAMP('24-08-2007 12:30', 'DD-MM-YYYY HH24:MI')
 7        AND TO_TIMESTAMP('24-08-2007 12:42', 'DD-MM-YYYY HH24:MI')
 8  WHERE deptno = 10;
StartTime         EndTime           Xid              O  EMPNO ENAME    SAL
----------------- ----------------- ---------------- - ------ ------ -----
24/08/07 12:40:12                   0200120099010000 U   7782 CLARK   2550
24/08/07 12:40:12                   0200120099010000 U   7839 KING    5100
24/08/07 12:40:12                   0200120099010000 U   7934 MILLER  1400
24/08/07 12:40:12                                        7782 CLARK   2450
24/08/07 12:40:12                                        7839 KING    5000
24/08/07 12:40:12                                        7934 MILLER  1300
scott@LAB10G> select
 2  undo_change#, operation, table_owner, table_name, row_id, undo_sql
 3  from flashback_transaction_query where xid = HEXTORAW('0200120099010000');
UNDO_CHANGE# OPERATION  TABLE_OWNE TABLE_NAME ROW_ID
------------ ---------- ---------- ---------- -------------------
UNDO_SQL
-------------------------------------------------------------------------------
 1 UPDATE     SCOTT      EMP_FLASH  AAANC8AAEAAAAGkAAU

update "SCOTT"."EMP_FLASH" set "SAL" = '2450' where ROWID = 'AAANC8AAEAAAAGkAAU';

 2 UPDATE     SCOTT      EMP_FLASH  AAANC8AAEAAAAGkAAW

update "SCOTT"."EMP_FLASH" set "SAL" = '5000' where ROWID = 'AAANC8AAEAAAAGkAAW';

 3 UPDATE     SCOTT      EMP_FLASH  AAANC8AAEAAAAGkAAb

update "SCOTT"."EMP_FLASH" set "SAL" = '1300' where ROWID = 'AAANC8AAEAAAAGkAAb';

 4 BEGIN


Otras operaciones

scott@LAB10G> delete from emp_flash where ename='MILLER';
1 fila suprimida.
scott@LAB10G> commit;
Confirmación terminada.
scott@LAB10G> insert into emp_flash
 2  values (8888, 'Barbiero', 'CLERK', 7782, sysdate, 1000, null, 10);
1 fila creada.
scott@LAB10G> commit;
Confirmación terminada.
scott@LAB10G> SELECT
 2  versions_starttime, versions_endtime,
 3  versions_xid, versions_operation, empno, ename, sal
 4  FROM emp_flash
 5  VERSIONS BETWEEN TIMESTAMP
 6           TO_TIMESTAMP('24-08-2007 12:30', 'DD-MM-YYYY HH24:MI')
 7       AND TO_TIMESTAMP('24-08-2007 13:14', 'DD-MM-YYYY HH24:MI')
 8  WHERE versions_operation <> 'U';
StartTime         EndTime           Xid              O  EMPNO ENAME        SAL
----------------- ----------------- ---------------- - ------ ---------- -----
24/08/07 13:13:38                   0A0007009B010000 I   8888 Barbiero    1000
24/08/07 13:11:59                   09000500A4010000 D   7934 MILLER      1400
scott@LAB10G> select
 2 undo_change#, operation, table_owner, table_name, row_id, undo_sql
 3  from flashback_transaction_query where xid = HEXTORAW('09000500A4010000');
UNDO_CHANGE# OPERATION  TABLE_OWNE TABLE_NAME ROW_ID
------------ ---------- ---------- ---------- -------------------
UNDO_SQL
-------------------------------------------------------------------------------
 1 DELETE     SCOTT      EMP_FLASH  AAANC8AAEAAAAGkAAb

Insert into "SCOTT"."EMP_FLASH" ("EMPNO", "ENAME", "JOB", "MGR", "HIREDATE", "SAL","COMM", "DEPTNO") values ('7934', 'MILLER', 'CLERK', '7782', TO_DATE('23/01/82','DD/MM/RR'), '1400', NULL, '10');

 2 BEGIN
scott@LAB10G> select
 2  undo_change#, operation, table_owner, table_name, row_id, undo_sql
 3  from flashback_transaction_query where xid = HEXTORAW('0A0007009B010000');
UNDO_CHANGE# OPERATION  TABLE_OWNE TABLE_NAME ROW_ID
------------ ---------- ---------- ---------- -------------------
UNDO_SQL
-------------------------------------------------------------------------------
 1 INSERT     SCOTT      EMP_FLASH  AAANC8AAEAAAAGkAAA

delete from "SCOTT"."EMP_FLASH" where ROWID = 'AAANC8AAEAAAAGkAAA';

 2 BEGIN


Entonces de la ejecución de los ejemplos observamos lo siguiente:

  • Aunque en los ejemplos solo accedí a la vista FLASHBACK_TRANSACTON_QUERY por xid, podría acceder por cualquiera de las columnas de la vista.
  • Las sentencias que generan cambios masivos (en mas de una fila), generan en FLASHBACK_TRANSACTION_QUERY tantas filas como filas modifiquen en la tabla.

Con Flashback Query, pude volverse atrás la información a nivel de fila mediante 2 métodos:

  1. Usando Oracle Flashback Query y cursores
  2. Usando Oracle Flashback Version Query y Oracle Flashback Transaction Query.

Ver también