You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 09:27:00