如果您的表有MONITORING,一种方法是只使用数据字典来查看表修改。如果MONITORING 处于打开状态,则以下方法应让您查看在给定时间段内哪些表已收到INSERTs(或UPDATEs 或DELETEs,如果需要)。
以下方法的缺点是必须等待 10 分钟才能检查已创建的内容,但它不需要表具有任何特定列。
更新:根据 Ikrom 的评论,最初的答案存在缺陷,只检查了一次数据字典。此答案已更新为检查两次以检测更改。
此方法将记录基线表修改计数,然后在 10 分钟后检查是否有任何更改。它使用两个工作表,一个用于参考ALL_TAB_MODIFICATIONS_REF,一个用于查看 10 分钟后修改的表ALL_TAB_MODIFICATIONS_COMPARE:
CREATE GLOBAL TEMPORARY TABLE
ALL_TAB_MODIFICATIONS_REF
ON COMMIT PRESERVE ROWS
AS SELECT * FROM ALL_TAB_MODIFICATIONS WHERE ROWNUM < 0;
CREATE GLOBAL TEMPORARY TABLE
ALL_TAB_MODIFICATIONS_COMPARE
ON COMMIT PRESERVE ROWS
AS SELECT * FROM ALL_TAB_MODIFICATIONS WHERE ROWNUM < 0;
Table created.
Table created.
创建这些工作表后,可以通过获取初始状态并在 10 分钟后与最终状态进行比较来检测任何更改。运行以下代码块后,可以查询ALL_TAB_MODIFICATIONS_COMPARE 以查看哪些表已被INSERTed。
BEGIN
--Flush monitoring info, to get a baseline.
DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO();
--Capture the initial state.
INSERT INTO ALL_TAB_MODIFICATIONS_REF
SELECT * FROM ALL_TAB_MODIFICATIONS;
COMMIT;
-- Wait ten minutes.
DBMS_LOCK.SLEEP(600);
--Flush monitoring info, to get a snapshot for comparison.
DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO();
-- Capture the final state.
INSERT INTO ALL_TAB_MODIFICATIONS_COMPARE
SELECT * FROM ALL_TAB_MODIFICATIONS
WHERE NOT EXISTS(SELECT 1 FROM ALL_TAB_MODIFICATIONS_REF
WHERE ALL_TAB_MODIFICATIONS_REF.TABLE_OWNER = ALL_TAB_MODIFICATIONS.TABLE_OWNER
AND ALL_TAB_MODIFICATIONS_REF.TABLE_NAME = ALL_TAB_MODIFICATIONS.TABLE_NAME
AND ALL_TAB_MODIFICATIONS_REF.INSERTS >= ALL_TAB_MODIFICATIONS.INSERTS);
COMMIT;
END;
/
运行块后,检查带有INSERTs 的表:
SELECT TABLE_NAME FROM ALL_TAB_MODIFICATIONS_COMPARE;
这是一个示例,用于检测一个表在 10 分钟内发生的更改,但排除另一个表,因为它自上次 INSERT 以来已超过 10 分钟:
创建测试表:
CREATE TABLE RECENT_DML (THE_DATA NUMBER, DML_TIME TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL);
CREATE TABLE NO_RECENT_DML (THE_DATA NUMBER, DML_TIME TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL);
Table created.
Table created.
并在两个表中添加一些初始测试数据。
INSERT INTO RECENT_DML (THE_DATA) VALUES (1);
INSERT INTO NO_RECENT_DML (THE_DATA) VALUES (1);
COMMIT;
1 row inserted.
1 row inserted.
Commit complete.
然后在上面的一个会话中运行上面的监控块,以检测 10 分钟后的变化。
当块在第一个会话中运行时,在第二个会话中将更多数据添加到仅RECENT_DML。
INSERT INTO RECENT_DML (THE_DATA) VALUES (1);
COMMIT;
1 row inserted.
Commit complete.
在第一个会话中块完成后,查询修改的表:
SELECT TABLE_NAME FROM ALL_TAB_MODIFICATIONS_COMPARE;
TABLE_NAME
RECENT_DML