如何在Oracle触发器中获取其他用户的精确更新列名(ERP场景)
Oracle触发器实现精确更新列捕获与操作日志存储
1. 创建操作日志表
先建立一张专门存储操作日志的表,记录所有关键变更细节:
CREATE TABLE OPERATION_LOG ( LOG_ID NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, TABLE_NAME VARCHAR2(50) NOT NULL, OPERATOR VARCHAR2(50) NOT NULL, OP_TIME TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, OP_TYPE VARCHAR2(10) NOT NULL, -- INSERT/UPDATE/DELETE UPDATED_COLUMN VARCHAR2(50) NOT NULL, OLD_VALUE VARCHAR2(200), NEW_VALUE VARCHAR2(200) );
2. 编写行级触发器捕获更新列
假设核心业务表是INVENTORY(包含STOCK_QTY库存剩余量、SOLD_QTY售出量字段),创建触发器监控该表的更新操作:
CREATE OR REPLACE TRIGGER TRG_INVENTORY_OP_LOG AFTER UPDATE ON INVENTORY FOR EACH ROW DECLARE V_CURRENT_USER VARCHAR2(50); BEGIN -- 获取当前执行操作的数据库用户,用来区分财务/仓储部门人员 V_CURRENT_USER := SYS_CONTEXT('USERENV', 'SESSION_USER'); -- 检查库存剩余量列是否被更新 IF UPDATING('STOCK_QTY') THEN INSERT INTO OPERATION_LOG (TABLE_NAME, OPERATOR, OP_TYPE, UPDATED_COLUMN, OLD_VALUE, NEW_VALUE) VALUES ('INVENTORY', V_CURRENT_USER, 'UPDATE', 'STOCK_QTY', :OLD.STOCK_QTY, :NEW.STOCK_QTY); END IF; -- 检查售出量列是否被更新 IF UPDATING('SOLD_QTY') THEN INSERT INTO OPERATION_LOG (TABLE_NAME, OPERATOR, OP_TYPE, UPDATED_COLUMN, OLD_VALUE, NEW_VALUE) VALUES ('INVENTORY', V_CURRENT_USER, 'UPDATE', 'SOLD_QTY', :OLD.SOLD_QTY, :NEW.SOLD_QTY); END IF; -- 可根据业务需求添加其他需监控的列(比如出库量字段) END; /
3. 核心要点
UPDATING()函数:Oracle原生函数,精准判断当前UPDATE语句是否修改了指定列,不会遗漏任何字段的变更。- 行级触发器:
FOR EACH ROW确保每一行数据的变更都被单独记录,适配多用户并发操作场景,避免批量更新导致的日志丢失。 - 操作人溯源:通过
SYS_CONTEXT获取的用户信息,结合ERP系统的用户权限配置,可直接区分财务/仓储部门的操作主体。 - 数据不一致排查:查询
OPERATION_LOG表,可按时间、操作人、列名筛选变更记录,对比仓储出库和管理模块售出的数值变更轨迹,快速定位差异产生的具体操作。
4. 优化建议
- 若需监控INSERT/DELETE操作,可修改触发器触发时机为
AFTER INSERT OR UPDATE OR DELETE,并添加对应分支逻辑。 - 高并发场景下,可采用Oracle AQ异步队列存储日志,避免同步写入日志表影响业务操作性能。
内容的提问来源于stack exchange,提问作者Yasir M Warid
相关产品推荐
相关产品推荐

