创建Oracle表变更审计触发器时遇NEW/OLD绑定变量错误求助
问题分析与解决方案
你的触发器错误根源在于更新操作分支中不必要地查询原表获取旧值,Oracle触发器的:OLD和:NEW绑定变量已经可以直接提供行修改前后的字段值,无需额外查询。
具体问题点:
- 在
UPDATING分支中,你通过SELECT NAME, LASTNAME INTO V_OLD_NAME, V_OLD_LASTNAME FROM CLIENTS WHERE CLIENT_ID = :OLD.CLIENT_ID获取旧值,这完全多余,且会导致日志记录错误(AFTER触发器执行时,原表行已更新,查询得到的是新值而非旧值)。 - 额外声明的变量
V_OLD_NAME、V_OLD_LASTNAME属于冗余代码,增加不必要的复杂度。
修正后的触发器代码:
CREATE OR REPLACE TRIGGER CLIENTS_LOG_TRIGGER AFTER INSERT OR UPDATE OR DELETE ON CLIENTS FOR EACH ROW BEGIN IF INSERTING THEN INSERT INTO CLIENTS_LOG (AUDIT_ID, CLIENT_ID, NEW_NAME, NEW_LASTNAME, MODIFICATION_DATE, MODIFYING_USER) VALUES (AUDIT_SEQ.NEXTVAL, :NEW.CLIENT_ID, :NEW.NAME, :NEW.LASTNAME, SYSTIMESTAMP, USER); ELSIF UPDATING THEN INSERT INTO CLIENTS_LOG (AUDIT_ID, CLIENT_ID, OLD_NAME, NEW_NAME, OLD_LASTNAME, NEW_LASTNAME, MODIFICATION_DATE, MODIFYING_USER) VALUES (AUDIT_SEQ.NEXTVAL, :OLD.CLIENT_ID, :OLD.NAME, :NEW.NAME, :OLD.LASTNAME, :NEW.LASTNAME, SYSTIMESTAMP, USER); ELSIF DELETING THEN INSERT INTO CLIENTS_LOG (AUDIT_ID, CLIENT_ID, OLD_NAME, OLD_LASTNAME, MODIFICATION_DATE, MODIFYING_USER) VALUES (AUDIT_SEQ.NEXTVAL, :OLD.CLIENT_ID, :OLD.NAME, :OLD.LASTNAME, SYSTIMESTAMP, USER); END IF; END; /
补充说明:
:OLD在INSERT操作中为NULL,在UPDATE/DELETE操作中保存修改/删除前的行数据;:NEW在DELETE操作中为NULL,在INSERT/UPDATE操作中保存插入/修改后的行数据;- 确保
AUDIT_SEQ序列已正确创建,若未创建可执行:
CREATE SEQUENCE AUDIT_SEQ START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
内容的提问来源于stack exchange,提问作者Daniel Felipe Castro Moreno
相关产品推荐
相关产品推荐

