创建增删改前时间校验与操作日志的数据库触发器技术咨询
没问题,我来帮你实现这个Oracle触发器的需求!
解决方案
首先确认你的system_events表结构符合需求,接下来我们创建满足时间检查+日志记录的触发器:
触发器代码
CREATE OR REPLACE TRIGGER check_operating_time_trg BEFORE INSERT OR UPDATE OR DELETE ON YOUR_TARGET_TABLE -- 替换成你要监控的表名 FOR EACH ROW DECLARE v_action VARCHAR2(10); v_current_hour NUMBER; BEGIN -- 1. 识别当前执行的操作类型 IF INSERTING THEN v_action := 'INSERT'; ELSIF UPDATING THEN v_action := 'UPDATE'; ELSIF DELETING THEN v_action := 'DELETE'; END IF; -- 2. 先记录操作日志到system_events表 INSERT INTO system_events (who, action, when) VALUES (USER, v_action, SYSDATE); -- 3. 检查当前是否为非工作时间(8:00 AM - 5:00 PM之外) v_current_hour := TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')); IF v_current_hour < 8 OR v_current_hour >= 17 THEN -- 抛出异常,自动撤销当前变更 RAISE_APPLICATION_ERROR(-20001, '非工作时间不允许执行数据变更操作!'); END IF; EXCEPTION WHEN OTHERS THEN -- 确保异常不吞掉日志(日志已提前插入,这里直接抛出原异常) RAISE; END; /
关键逻辑解释
- 触发规则:
BEFORE INSERT OR UPDATE OR DELETE确保在任何增删改操作执行前触发;FOR EACH ROW表示对每一行变更都做检查(如果不需要行级监控,可改成STATEMENT级提升效率)。 - 操作类型识别:利用Oracle内置的
INSERTING/UPDATING/DELETING函数判断当前操作,赋值给变量用于日志记录。 - 日志记录:用
USER函数获取当前登录用户,SYSDATE获取操作时间,直接写入system_events表。 - 时间检查:通过
TO_CHAR(SYSDATE, 'HH24')提取24小时制的当前小时,判断是否在8点前或17点及之后(你可以根据实际工作时间调整边界值)。 - 变更撤销:一旦检测到非工作时间,调用
RAISE_APPLICATION_ERROR抛出自定义异常,Oracle会自动回滚当前的变更操作。
额外优化建议
- 记得把代码里的
YOUR_TARGET_TABLE替换成你实际要监控的表名。 - 如果需要排除周末,可在时间检查逻辑里增加星期判断:
IF TO_CHAR(SYSDATE, 'DY', 'NLS_DATE_LANGUAGE=AMERICAN') IN ('SAT', 'SUN') OR v_current_hour < 8 OR v_current_hour >= 17 THEN RAISE_APPLICATION_ERROR(-20001, '非工作时间或周末不允许执行数据变更操作!'); END IF; - 确保创建触发器的用户拥有
system_events表的插入权限,以及目标表的触发器创建权限。
内容的提问来源于stack exchange,提问作者Lenz Vital
相关产品推荐
相关产品推荐

