[oracle] How to find out when an Oracle table was updated the last time

Can I find out when the last INSERT, UPDATE or DELETE statement was performed on a table in an Oracle database and if so, how?

A little background: The Oracle version is 10g. I have a batch application that runs regularly, reads data from a single Oracle table and writes it into a file. I would like to skip this if the data hasn't changed since the last time the job ran.

The application is written in C++ and communicates with Oracle via OCI. It logs into Oracle with a "normal" user, so I can't use any special admin stuff.

Edit: Okay, "Special Admin Stuff" wasn't exactly a good description. What I mean is: I can't do anything besides SELECTing from tables and calling stored procedures. Changing anything about the database itself (like adding triggers), is sadly not an option if want to get it done before 2010.

This question is related to oracle oracle-call-interface

The answer is


You would need to add a trigger on insert, update, delete that sets a value in another table to sysdate.

When you run application, it would read the value and save it somewhere so that the next time it is run it has a reference to compare.

Would you consider that "Special Admin Stuff"?

It would be better to describe what you're actually doing so you get clearer answers.


I'm really late to this party but here's how I did it:

SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable;

It's close enough for my purposes.


You would need to add a trigger on insert, update, delete that sets a value in another table to sysdate.

When you run application, it would read the value and save it somewhere so that the next time it is run it has a reference to compare.

Would you consider that "Special Admin Stuff"?

It would be better to describe what you're actually doing so you get clearer answers.


How long does the batch process take to write the file? It may be easiest to let it go ahead and then compare the file against a copy of the file from the previous run to see if they are identical.


Ask your DBA about auditing. He can start an audit with a simple command like :

AUDIT INSERT ON user.table

Then you can query the table USER_AUDIT_OBJECT to determine if there has been an insert on your table since the last export.

google for Oracle auditing for more info...


Oracle can watch tables for changes and when a change occurs can execute a callback function in PL/SQL or OCI. The callback gets an object that's a collection of tables which changed, and that has a collection of rowid which changed, and the type of action, Ins, upd, del.

So you don't even go to the table, you sit and wait to be called. You'll only go if there are changes to write.

It's called Database Change Notification. It's much simpler than CDC as Justin mentioned, but both require some fancy admin stuff. The good part is that neither of these require changes to the APPLICATION.

The caveat is that CDC is fine for high volume tables, DCN is not.


Ask your DBA about auditing. He can start an audit with a simple command like :

AUDIT INSERT ON user.table

Then you can query the table USER_AUDIT_OBJECT to determine if there has been an insert on your table since the last export.

google for Oracle auditing for more info...


SELECT * FROM all_tab_modifications;

Could you run a checksum of some sort on the result and store that locally? Then when your application queries the database, you can compare its checksum and determine if you should import it?

It looks like you may be able to use the ORA_HASH function to accomplish this.

Update: Another good resource: 10g’s ORA_HASH function to determine if two Oracle tables’ data are equal


Ask your DBA about auditing. He can start an audit with a simple command like :

AUDIT INSERT ON user.table

Then you can query the table USER_AUDIT_OBJECT to determine if there has been an insert on your table since the last export.

google for Oracle auditing for more info...


You would need to add a trigger on insert, update, delete that sets a value in another table to sysdate.

When you run application, it would read the value and save it somewhere so that the next time it is run it has a reference to compare.

Would you consider that "Special Admin Stuff"?

It would be better to describe what you're actually doing so you get clearer answers.


Could you run a checksum of some sort on the result and store that locally? Then when your application queries the database, you can compare its checksum and determine if you should import it?

It looks like you may be able to use the ORA_HASH function to accomplish this.

Update: Another good resource: 10g’s ORA_HASH function to determine if two Oracle tables’ data are equal


If the auditing is enabled on the server, just simply use

SELECT *
FROM ALL_TAB_MODIFICATIONS
WHERE TABLE_NAME IN ()

If any one is still looking for an answer they can use Oracle Database Change Notification feature coming with Oracle 10g. It requires CHANGE NOTIFICATION system privilege. You can register listeners when to trigger a notification back to the application.


Could you run a checksum of some sort on the result and store that locally? Then when your application queries the database, you can compare its checksum and determine if you should import it?

It looks like you may be able to use the ORA_HASH function to accomplish this.

Update: Another good resource: 10g’s ORA_HASH function to determine if two Oracle tables’ data are equal


If the auditing is enabled on the server, just simply use

SELECT *
FROM ALL_TAB_MODIFICATIONS
WHERE TABLE_NAME IN ()

How long does the batch process take to write the file? It may be easiest to let it go ahead and then compare the file against a copy of the file from the previous run to see if they are identical.


Oracle can watch tables for changes and when a change occurs can execute a callback function in PL/SQL or OCI. The callback gets an object that's a collection of tables which changed, and that has a collection of rowid which changed, and the type of action, Ins, upd, del.

So you don't even go to the table, you sit and wait to be called. You'll only go if there are changes to write.

It's called Database Change Notification. It's much simpler than CDC as Justin mentioned, but both require some fancy admin stuff. The good part is that neither of these require changes to the APPLICATION.

The caveat is that CDC is fine for high volume tables, DCN is not.


Oracle can watch tables for changes and when a change occurs can execute a callback function in PL/SQL or OCI. The callback gets an object that's a collection of tables which changed, and that has a collection of rowid which changed, and the type of action, Ins, upd, del.

So you don't even go to the table, you sit and wait to be called. You'll only go if there are changes to write.

It's called Database Change Notification. It's much simpler than CDC as Justin mentioned, but both require some fancy admin stuff. The good part is that neither of these require changes to the APPLICATION.

The caveat is that CDC is fine for high volume tables, DCN is not.


How long does the batch process take to write the file? It may be easiest to let it go ahead and then compare the file against a copy of the file from the previous run to see if they are identical.


Ask your DBA about auditing. He can start an audit with a simple command like :

AUDIT INSERT ON user.table

Then you can query the table USER_AUDIT_OBJECT to determine if there has been an insert on your table since the last export.

google for Oracle auditing for more info...


Could you run a checksum of some sort on the result and store that locally? Then when your application queries the database, you can compare its checksum and determine if you should import it?

It looks like you may be able to use the ORA_HASH function to accomplish this.

Update: Another good resource: 10g’s ORA_HASH function to determine if two Oracle tables’ data are equal


Please use the below statement

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

You would need to add a trigger on insert, update, delete that sets a value in another table to sysdate.

When you run application, it would read the value and save it somewhere so that the next time it is run it has a reference to compare.

Would you consider that "Special Admin Stuff"?

It would be better to describe what you're actually doing so you get clearer answers.


SELECT * FROM all_tab_modifications;

Please use the below statement

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

I'm really late to this party but here's how I did it:

SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable;

It's close enough for my purposes.


If any one is still looking for an answer they can use Oracle Database Change Notification feature coming with Oracle 10g. It requires CHANGE NOTIFICATION system privilege. You can register listeners when to trigger a notification back to the application.


Oracle can watch tables for changes and when a change occurs can execute a callback function in PL/SQL or OCI. The callback gets an object that's a collection of tables which changed, and that has a collection of rowid which changed, and the type of action, Ins, upd, del.

So you don't even go to the table, you sit and wait to be called. You'll only go if there are changes to write.

It's called Database Change Notification. It's much simpler than CDC as Justin mentioned, but both require some fancy admin stuff. The good part is that neither of these require changes to the APPLICATION.

The caveat is that CDC is fine for high volume tables, DCN is not.