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.
If you wish to get the last updated row, just enable auditing for table and query (timestamp column of dba_audit_trail view) and forget all rest thing.
SELECT name AS TableName, create_date AS CreatedDate, modify_date as ModifyDate FROM sys. tables order by ModifyDate; ...will tell me the last time a table was created and modified (from a DDL perspective).
LAST_DDL_TIME is the last time the table had a DDL (structure) change applied, but does NOT include DML (data).
The last DDL time is easy: select last_ddl_time from user_objects where object_name = :tab; As you're finding, if you've not got auditing, last DML write time is a little trickier...
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.
Since you are on 10g, you could potentially use the ORA_ROWSCN
pseudocolumn. That gives you an upper bound of the last SCN (system change number) that caused a change in the row. Since this is an increasing sequence, you could store off the maximum ORA_ROWSCN
that you've seen and then look only for data with an SCN greater than that.
By default, ORA_ROWSCN
is actually maintained at the block level, so a change to any row in a block will change the ORA_ROWSCN
for all rows in the block. This is probably quite sufficient if the intention is to minimize the number of rows you process multiple times with no changes if we're talking about "normal" data access patterns. You can rebuild the table with ROWDEPENDENCIES
which will cause the ORA_ROWSCN
to be tracked at the row level, which gives you more granular information but requires a one-time effort to rebuild the table.
Another option would be to configure something like Change Data Capture (CDC) and to make your OCI application a subscriber to changes to the table, but that also requires a one-time effort to configure CDC.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With