如何找出最后一次更新Oracle表的时间
我可以知道什么时候在Oracle数据库的表上执行了最后一个INSERT,UPDATE或DELETE语句,如果是这样,怎么办?
一点背景:Oracle版本是10g。 我有一个定期运行的批处理应用程序,从单个Oracle表读取数据并将其写入文件。 如果自上次作业运行以来数据没有改变,我想跳过这一步。
该应用程序是用C ++编写的,并通过OCI与Oracle进行通信。 它使用“普通”用户loginOracle,所以我不能使用任何特殊的pipe理员东西。
编辑:好吧,“特别pipe理员”不完全是一个好的描述。 我的意思是:除了从表中select和调用存储过程外,我什么也做不了。 如果想在2010年之前完成,那么改变数据库本身的任何东西(比如添加触发器)是不幸的。
既然你是在10g,你可能会使用ORA_ROWSCN
伪列。 这给你一个导致行改变的最后一个SCN(系统改变号)的上界。 由于这是一个递增的顺序,所以你可以存储你所看到的最大的ORA_ROWSCN
,然后只查看SCN大于那个的数据。
默认情况下, ORA_ROWSCN
实际上是在块级维护的,所以对块中任何一行的改变都会改变ORA_ROWSCN
中所有行的ORA_ROWSCN
。 如果我们正在讨论“正常”的数据访问模式,那么这样做的目的可能就是将多次处理的行数减到最less而不做任何修改。 您可以使用ROWDEPENDENCIES
重build表,这将导致在行级别跟踪ORA_ROWSCN
,从而为您提供更详细的信息,但需要一次性重新ROWDEPENDENCIES
表。
另一个select是configuration类似于更改数据捕获(CDC)的内容,并使您的OCI应用程序成为订户更改表,但这也需要一次性configurationCDC。
我真的很晚参加这个派对,但是我是这么做的:
SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable;
这足够接近我的目的。
询问您的DBA审计。 他可以用一个简单的命令开始审计,如:
AUDIT INSERT ON user.table
然后,您可以查询表USER_AUDIT_OBJECT以确定自上次导出以来是否在表上存在插入。
谷歌为Oracle审计的更多信息…
你可以在结果上运行某种校验和并在本地存储吗? 那么当你的应用程序查询数据库时,你可以比较它的校验和,并确定你是否应该导入它?
它看起来像你可能能够使用ORA_HASHfunction来完成这一点。
更新:另一个好的资源: 10g的ORA_HASH函数来确定两个Oracle表的数据是否相等
SELECT * FROM all_tab_modifications;
Oracle可以监视表的更改,当发生更改时可以在PL / SQL或OCI中执行callback函数。 callback得到一个对象,这个对象是一个被改变的表集合,并且有一个更改的rowid集合,以及动作typesIns,upd,del。
所以你甚至不去餐桌,坐着等着被叫。 只有在写入有变化的情况下才能进行。
这就是所谓的数据库更改通知 。 Justin提到,它比CDC简单得多,但都需要一些花哨的pipe理员的东西。 好的部分是这些都不需要改变应用程序。
需要注意的是,CDC适用于大容量的表格,而DCN则不适用。
您需要在插入,更新,删除时添加一个触发器,将另一个表中的值设置为sysdate。
当你运行应用程序时,它会读取值并保存在某个地方,以便下一次运行它时有一个比较的参考。
你会认为“特殊pipe理的东西”?
最好能描述一下你在做什么,这样你就能得到更清晰的答案。
批处理需要多长时间来写入文件? 让它继续下去可能是最容易的,然后将文件与上一次运行的文件副本进行比较,看它们是否相同。
如果有人还在寻找答案,他们可以使用Oracle 10g附带的Oracle 数据库更改通知function。 它需要CHANGE NOTIFICATION
系统特权。 您可以注册侦听器何时触发通知回到应用程序。
请使用下面的语句
select * from all_objects ao where ao.OBJECT_TYPE = 'TABLE' and ao.OWNER = 'YOUR_SCHEMA_NAME'