Oracle Flashback Transaction Query
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)
Contenido
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:
- Usando Oracle Flashback Query y cursores
- Usando Oracle Flashback Version Query y Oracle Flashback Transaction Query.