35

我能否查明对 Oracle 数据库中的表执行最后一次 INSERT、UPDATE 或 DELETE 语句的时间?如果可以,如何查明?

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

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

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

4

11 回答 11

62

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

SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable;

对于我的目的来说,它已经足够接近了。

于 2011-07-26T15:35:33.480 回答
41

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

默认情况下,ORA_ROWSCN实际上是在块级别维护的,因此对块中任何行的更改都会更改块中ORA_ROWSCN的所有行。如果我们谈论的是“正常”数据访问模式,那么这可能就足够了。您可以重建ROWDEPENDENCIES将导致ORA_ROWSCN在行级别跟踪的表,这为您提供更细化的信息,但需要一次性努力来重建表。

另一种选择是配置更改数据捕获 (CDC) 之类的东西,并使您的 OCI 应用程序成为表更改的订阅者,但这也需要一次性配置 CDC。

于 2008-11-05T15:33:13.350 回答
12

向您的 DBA 询问有关审计的问题。他可以使用以下简单命令开始审核:

AUDIT INSERT ON user.table

然后您可以查询表 USER_AUDIT_OBJECT 以确定自上次导出以来您的表上是否有插入。

google for Oracle 审计以获取更多信息...

于 2008-11-05T14:35:47.287 回答
11
SELECT * FROM all_tab_modifications;
于 2014-08-25T14:41:15.657 回答
6

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

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

更新:另一个很好的资源:10g 的 ORA_HASH 函数来确定两个 Oracle 表的数据是否相等

于 2008-11-05T13:59:05.863 回答
5

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

所以你甚至不去桌子,你坐等被叫。只有在有更改要写入时,您才会去。

它称为数据库更改通知。正如贾斯汀所说,它比 CDC 简单得多,但两者都需要一些花哨的管理内容。好的部分是这些都不需要更改应用程序。

需要注意的是,CDC 适用于大容量表,而 DCN 则不然。

于 2008-11-05T16:27:17.267 回答
3

如果在服务器上启用了审计,只需简单地使用

SELECT *
FROM ALL_TAB_MODIFICATIONS
WHERE TABLE_NAME IN ()
于 2018-12-13T13:41:41.237 回答
2

您需要在插入、更新、删除时添加一个触发器,将另一个表中的值设置为 sysdate。

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

你会考虑那个“特殊的管理东西”吗?

最好描述一下您实际在做什么,以便您获得更清晰的答案。

于 2008-11-05T13:34:35.570 回答
1

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

于 2008-11-05T14:19:40.783 回答
0

如果有人仍在寻找答案,他们可以使用Oracle 10g 附带的 Oracle Database Change Notification特性。它需要CHANGE NOTIFICATION系统特权。您可以注册侦听器何时触发返回给应用程序的通知。

于 2016-07-26T09:05:14.770 回答
-5

请使用以下语句

select * from all_objects ao where ao.OBJECT_TYPE = 'TABLE'  and ao.OWNER = 'YOUR_SCHEMA_NAME'
于 2013-04-24T11:01:09.523 回答