2008-11-05 58 views
21

¿Puedo averiguar cuándo se realizó la última declaración INSERTAR, ACTUALIZAR o ELIMINAR en una tabla en una base de datos Oracle y, de ser así, cómo?Cómo saber cuándo se actualizó una tabla de Oracle la última vez

Un poco de historia: la versión de Oracle es 10g. Tengo una aplicación por lotes que se ejecuta regularmente, lee datos de una sola tabla de Oracle y los escribe en un archivo. Me gustaría omitir esto si los datos no han cambiado desde la última vez que se ejecutó el trabajo.

La aplicación está escrita en C++ y se comunica con Oracle a través de OCI. Se registra en Oracle con un usuario "normal", por lo que no puedo usar ningún administrador especial.

Editar: Bien, "Special Admin Stuff" no era exactamente una buena descripción. Lo que quiero decir es: no puedo hacer nada más que SELECCIONAR de tablas y llamar a procedimientos almacenados. Cambiar algo sobre la base de datos en sí misma (como agregar activadores), lamentablemente no es una opción si desea hacerlo antes de 2010.

+0

Sí ... el comentario de 2010 es sobre la lentitud de sus DBAs ¿Lo tomo? –

+0

Bueno, tipo de. Son lentos, pero como dije en un comentario anterior, los entiendo. Si hay un problema con esta base de datos, se vuelve realmente feo, muy rápido. Puedes conseguir cosas allí, pero solo después de que un grupo de personas lo analizó al demonio. – Maximilian

Respuesta

35

ya que estás en 10g, se puede usar potencialmente la pseudocolumna ORA_ROWSCN. Eso le da un límite superior del último SCN (número de cambio del sistema) que causó un cambio en la fila. Como esta es una secuencia creciente, puede almacenar el máximo ORA_ROWSCN que haya visto y luego buscar solo datos con un SCN mayor que ese.

De manera predeterminada, ORA_ROWSCN se mantiene en realidad en el nivel del bloque, por lo que un cambio a cualquier fila en un bloque cambiará el ORA_ROWSCN para todas las filas del bloque. Esto probablemente sea suficiente si la intención es minimizar el número de filas que procesa varias veces sin cambios si hablamos de patrones de acceso a datos "normales".Puede reconstruir la tabla con ROWDEPENDENCIES, lo que hará que se rastree el ORA_ROWSCN en el nivel de fila, lo que le brinda más información granular pero requiere un esfuerzo único para reconstruir la tabla.

Otra opción sería configurar algo como Change Data Capture (CDC) y hacer que su aplicación OCI sea suscriptora de los cambios en la tabla, pero eso también requiere un esfuerzo por una sola vez para configurar CDC.

+0

Whoa, eso es realmente genial. Me he perdido esa pseudocolumna. pero no usaría CDC ... demasiado complejo para sus propósitos. Usaría DCN (notificación de cambio de base de datos). –

+0

Gracias! También muy útil. – Maximilian

+1

¿Qué es una fila se borra? ¿Cómo puedo averiguarlo? –

1

Debería agregar un desencadenador en insertar, actualizar, eliminar que establece un valor en otra tabla para sysdate

Cuando ejecute la aplicación, leerá el valor y lo guardará en algún lugar para que la próxima vez que se ejecute tenga una referencia para comparar.

¿Consideraría que "Special Admin Stuff"?

Sería mejor describir lo que estás haciendo en realidad para que obtengas respuestas más claras.

5

¿Podría ejecutar una suma de comprobación de algún tipo en el resultado y almacenarlo localmente? Luego, cuando su aplicación consulte la base de datos, puede comparar su suma de comprobación y determinar si debe importarla.

Parece que es posible que pueda utilizar la función ORA_HASH para lograr esto.

Actualización: Otro buen recurso: 10g’s ORA_HASH function to determine if two Oracle tables’ data are equal

+0

Eso parece prometedor. ¡Gracias! – Maximilian

+0

Buena suerte :) (Estaré agregando esto a mi "caja de herramientas" también, ¡así que aprendí algo nuevo también!) – mwilliams

+0

Suena interesante. ¿Puedes incluir un ejemplo de crear un hash para una tabla? –

1

¿Cuánto tiempo toma el proceso por lotes para escribir el archivo? Puede ser más fácil dejar que avance y luego comparar el archivo con una copia del archivo de la ejecución anterior para ver si son idénticos.

+0

Ese es el problema: no solo escribo los datos, sino que debo procesarlos de una manera complicada. Esto lleva varias horas y esto es lo que trato de evitar. – Maximilian

9

Pregunte a su DBA acerca de la auditoría. Se puede iniciar una auditoría con un comando simple como:

AUDIT INSERT ON user.table 

A continuación puede consultar la USER_AUDIT_OBJECT tabla para determinar si ha habido una inserción en su mesa desde la última exportación.

Google para Oracle auditoría para más información ...

+1

Gracias. Supongo que esta es la manera en que se supone que debe hacerse. Lamentablemente, "Preguntar al DBA" tiende a ser bastante complicado. Son realmente paranoicos sobre cambiar cosas. Yo los entiendo. Si algo está mal con este DB, las cosas tienden a ponerse feas. – Maximilian

3

Oracle puede ver las tablas de cambios y cuando se produce un cambio puede ejecutar una función de devolución de llamada en PL/SQL u OCI. La devolución de llamada obtiene un objeto que es una colección de tablas que cambió, y que tiene una colección de rowid que cambió, y el tipo de acción, Ins, upd, del.

Así que ni siquiera vas a la mesa, te sientas y esperas que te llamen. Solo irás si hay cambios para escribir.

Se llama Database Change Notification. Es mucho más simple que CDC como mencionó Justin, pero ambos requieren algunas cosas de administración sofisticadas. Lo bueno es que ninguno de estos requiere cambios en la APLICACIÓN.

La advertencia es que CDC está bien para tablas de alto volumen, DCN no lo es.

+0

FWIW, recientemente descubrí que CQN (es decir, CDN) no es compatible con los PDB de 12c. Espero que sea en el futuro. – ddevienne

38

Estoy muy tarde para este partido pero aquí es cómo lo hice:

SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable; 

Está lo suficientemente cerca para mis propósitos.

+4

Funciona siempre y cuando la última actualización de su tabla no haya sido hace mucho tiempo. Si recibes un error, entonces es más seguro hacer primero un: left sys.smon_scn_time tiemposmax en myTable.ora_rowscn <= tiemposmax.scn y luego aplicar SCN_TO_TIMESTAMP al ora_rowscn de tu tabla si y solo si hay una coincidencia.De lo contrario, puede visualizar SCN_TO_TIMESTAMP (MIN (SCN)) de sys.smon_scn_time como la fecha más temprana en que se modificó la tabla. –

-3

Utilice la siguiente declaración

select * from all_objects ao where ao.OBJECT_TYPE = 'TABLE' and ao.OWNER = 'YOUR_SCHEMA_NAME' 
+0

-1: No aborda la pregunta. –

+0

ha dirigido la pregunta a la dirección diferente –

6
SELECT * FROM all_tab_modifications; 
+0

Esto requeriría que primero recopile estadísticas en la tabla, ya que solo muestra cambios después de la última recopilación de estadísticas. – Superdooperhero

0

Si alguno todavía está buscando una respuesta que pueden utilizar Oracle Database Change Notification característica viene con Oracle 10g. Requiere el privilegio del sistema CHANGE NOTIFICATION. Puede registrar oyentes cuando se activa una notificación de vuelta a la aplicación.

Cuestiones relacionadas