如何确定Oracle表上次更新的时间

如何确定Oracle表上次更新的时间,oracle,oracle-call-interface,Oracle,Oracle Call Interface,我是否可以找出上次INSERT、UPDATE或DELETE语句是何时对Oracle数据库中的表执行的,如果是,如何执行 一点背景:Oracle版本是10g。我有一个定期运行的批处理应用程序,从单个Oracle表中读取数据并将其写入文件。如果自上次作业运行以来数据没有更改,我希望跳过此操作 应用程序是用C++编写的,通过OCI与Oracle通信。它使用“普通”用户登录到Oracle,所以我不能使用任何特殊的管理功能 编辑:好吧,“特别管理员的东西”并不是一个很好的描述。我的意思是:除了从表中选择和

我是否可以找出上次INSERT、UPDATE或DELETE语句是何时对Oracle数据库中的表执行的,如果是,如何执行

一点背景:Oracle版本是10g。我有一个定期运行的批处理应用程序,从单个Oracle表中读取数据并将其写入文件。如果自上次作业运行以来数据没有更改,我希望跳过此操作

应用程序是用C++编写的,通过OCI与Oracle通信。它使用“普通”用户登录到Oracle,所以我不能使用任何特殊的管理功能


编辑:好吧,“特别管理员的东西”并不是一个很好的描述。我的意思是:除了从表中选择和调用存储过程之外,我什么都做不了。如果您想在2010年之前完成数据库本身的任何更改(如添加触发器),很遗憾,这不是一个选项。

您需要在insert、update、delete上添加触发器,将另一个表中的值设置为sysdate

当您运行应用程序时,它将读取该值并将其保存在某个位置,以便下次运行时有一个要比较的引用

你认为那是“特别行政事务”吗?


最好描述一下你实际上在做什么,这样你才能得到更清楚的答案。

你能对结果运行某种校验和并将其存储在本地吗?然后,当应用程序查询数据库时,可以比较其校验和并确定是否应导入它

看起来您可以使用该函数来完成此操作


更新:另一个好资源:

批处理过程需要多长时间来写入文件?让它继续运行,然后将文件与上一次运行的文件副本进行比较,看看它们是否相同,这可能是最简单的方法。

询问您的DBA有关审核的问题。他可以使用以下简单命令启动审核:

AUDIT INSERT ON user.table
然后,您可以查询表用户\u AUDIT\u对象,以确定自上次导出以来表上是否有插入


google for Oracle auditing获取更多信息…

由于您使用的是10g,因此您可能会使用
ORA_ROWSCN
伪列。这将为您提供导致行中发生更改的最后一个SCN(系统更改编号)的上限。由于这是一个递增序列,您可以存储您看到的最大值
ORA_ROWSCN
,然后只查找SCN大于该值的数据

默认情况下,
ORA_ROWSCN
实际上保持在块级别,因此对块中任何行的更改都会更改块中所有行的
ORA_ROWSCN
。如果我们讨论的是“正常”数据访问模式,那么这可能就足够了,目的是在不做任何更改的情况下最小化多次处理的行数。您可以使用
ROWDEPENDENCIES
重新生成表,这将导致在行级别跟踪
ORA_ROWSCN
,这将为您提供更详细的信息,但需要一次性重新生成表


另一个选项是配置更改数据捕获(CDC)之类的内容,并使您的OCI应用程序成为表更改的订阅服务器,但这也需要一次性配置CDC。

Oracle可以监视表的更改,并且在发生更改时可以在PL/SQL或OCI中执行回调函数。回调获取一个对象,该对象是一个已更改的表集合,具有一个已更改的rowid集合,以及操作类型Ins、upd、del

所以你甚至不去吃饭,而是坐着等着别人叫你。只有在要写入的内容发生更改时,您才会去

它叫。正如Justin提到的,它比CDC简单得多,但两者都需要一些高级的管理功能。好的方面是,这两种方法都不需要对应用程序进行更改


需要注意的是,CDC可以用于高容量的表格,而DCN则不行。

我参加这个聚会真的迟到了,但我是这样做的:

SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable;

就我而言,这已经足够近了。

请使用下面的语句

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

如果有人仍在寻找答案,他们可以使用Oracle 10g附带的功能。它需要
更改通知
系统权限。您可以在何时触发回应用程序的通知时注册侦听器

如果在服务器上启用了审核,只需使用

SELECT *
FROM ALL_TAB_MODIFICATIONS
WHERE TABLE_NAME IN ()

听起来很有趣。你能举一个为表创建散列的例子吗?这就是问题所在:我不只是写数据,而是需要以一种复杂的方式处理它。这需要几个小时,这就是我想要避免的。谢谢。我想这是应该做的。遗憾的是,“询问DBA”往往相当复杂。他们对改变东西真的很偏执。我确实理解他们。如果这个数据库出了什么问题,事情就会变得很糟糕。是的。。。2010年的评论是关于DBA的缓慢,我想是吧?嗯,有点。他们很慢,但正如我在早些时候的评论中所说,我理解他们。如果这个数据库有问题,它会变得非常丑陋,非常快。你可以在那里得到一些东西,但必须经过一群人的分析。因为我还不能对答案发表评论(我是新来的),我想评论一下,我发现CDC已经从Oracle 12c中删除,以促使人们购买GoldenGate。哇,太酷了。我错过了那个专栏。但我不会用CDC。。。对他的目的来说太复杂了。我会使用DCN(数据库更改通知)。删除的行是什么?我怎么才能知道呢?只要上次更新您的表不是很久以前就行了。否则会出现错误,因此最安全的做法是首先在myTable上执行:left join sys.smon_scn_time tiemposmax.ora_rowscn FWIW,我最近发现12c的PDB不支持CQN(即CDN)。你把这个问题提到了不同的方向,但这并不能回答这个问题的答案
SELECT *
FROM ALL_TAB_MODIFICATIONS
WHERE TABLE_NAME IN ()