Oracle如何同时阻塞指定时段的表操作并记录操作尝试到审计表
问题根因
你现有代码的逻辑顺序错误:提前抛出Period_error异常后,后续的审计表插入代码完全没有执行机会,异常被捕获后直接返回报错,自然无法留下操作记录。
另外你忽略了Oracle事务的一致性特性:如果不做特殊处理,抛出应用错误触发主事务回滚时,你在触发器内写入的审计记录也会被同步回滚,一样留不下日志。
修复方案
调整逻辑顺序+新增自治事务处理即可,修正后的完整代码如下:
-- 审计表结构(你原有代码没问题,保留即可) CREATE TABLE Rent_Audit ( Attempt_Date DATE, Operation VARCHAR2(10), Table_Affected VARCHAR2(10) ); Create or replace trigger audit_trigger Before insert or update on rents DECLARE Period_error EXCEPTION; -- 自治事务审计写入过程,独立于主事务提交 PROCEDURE save_audit_log(op_type VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO Rent_Audit VALUES (SYSDATE, op_type, 'Rents'); COMMIT; -- 仅提交审计日志,不影响主事务 END save_audit_log; BEGIN -- 第一步:先写入操作审计日志 IF INSERTING THEN save_audit_log('Insert'); ELSIF UPDATING THEN save_audit_log('Update'); END IF; -- 第二步:判断时段,不符合要求直接抛出异常阻塞操作 -- 注意你原有代码写的是06-10点限制,按照需求调整为19点到24点(即19:00:00到23:59:59) IF TO_CHAR(sysdate, 'HH24MMSS') BETWEEN '190000' AND '235959' THEN RAISE Period_error; END IF; EXCEPTION WHEN Period_error THEN RAISE_APPLICATION_ERROR (-20001, '19:00~24:00时段不允许对rents表执行插入/更新操作'); END; /
关键说明
- 自治事务标识
PRAGMA AUTONOMOUS_TRANSACTION会让审计日志的写入成为独立事务,不受主事务回滚影响,哪怕操作被阻塞回滚,审计记录依然会保留 - 调整执行顺序后先写日志再做异常拦截,避免出现日志写入代码无法执行的问题
- 时段判断可根据你的实际需求调整精度,按小时判断可以直接写
TO_CHAR(sysdate, 'HH24') BETWEEN '19' AND '23',逻辑更简洁
内容的提问来源于stack exchange,提问作者samsom21
相关产品推荐
相关产品推荐

