SQL审计触发器编译错误求助:更新OPS_BUILD_ACTIVITY_LABEL时插入日志
解决ORA-00984和PL/SQL编译错误的触发器问题
嘿,我来帮你搞定这个触发器的问题!你遇到的PL/SQL: ORA-00984: column not allowed here错误,核心原因是在引用触发器的:OLD和:NEW伪记录时漏掉了前面的冒号——Oracle要求必须用:OLD和:NEW(带冒号)来访问触发前后的列值,而不是直接写OLD或NEW。
另外,你的触发器只处理了ACTIVITY_LABEL列的更新,但需求里提到当ACTIVITY_LABEL和NOTES列发生更新时都要插入审计记录,所以我们需要分别判断这两列是否被修改,然后各自插入对应的审计行。
下面是修正后的完整触发器代码:
create or replace TRIGGER ACTIVITY_LABEL_TRIGGER AFTER UPDATE OF ACTIVITY_LABEL, NOTES ON OPS_BUILD_ACTIVITY_LABEL FOR EACH ROW BEGIN -- 处理ACTIVITY_LABEL列的更新 IF :OLD.ACTIVITY_LABEL != :NEW.ACTIVITY_LABEL OR (:OLD.ACTIVITY_LABEL IS NULL AND :NEW.ACTIVITY_LABEL IS NOT NULL) OR (:OLD.ACTIVITY_LABEL IS NOT NULL AND :NEW.ACTIVITY_LABEL IS NULL) THEN INSERT INTO ACTIVITY_LABEL_AUDIT_LOG ( TABLE_NAME, COLUMN_NAME, OLD_VALUE, NEW_VALUE, UPDATED_BY, UPDATED_DTM ) VALUES ( 'OPS_BUILD_ACTIVITY_LABEL', 'ACTIVITY_LABEL', :OLD.ACTIVITY_LABEL, :NEW.ACTIVITY_LABEL, :NEW.LAST_UPDATED_BY, :NEW.LAST_UPDATED_DTM ); END IF; -- 处理NOTES列的更新 IF :OLD.NOTES != :NEW.NOTES OR (:OLD.NOTES IS NULL AND :NEW.NOTES IS NOT NULL) OR (:OLD.NOTES IS NOT NULL AND :NEW.NOTES IS NULL) THEN INSERT INTO ACTIVITY_LABEL_AUDIT_LOG ( TABLE_NAME, COLUMN_NAME, OLD_VALUE, NEW_VALUE, UPDATED_BY, UPDATED_DTM ) VALUES ( 'OPS_BUILD_ACTIVITY_LABEL', 'NOTES', :OLD.NOTES, :NEW.NOTES, :NEW.LAST_UPDATED_BY, :NEW.LAST_UPDATED_DTM ); END IF; END; /
关键修正点说明:
- 添加冒号:把所有的
OLD.xxx和NEW.xxx改成:OLD.xxx和:NEW.xxx,这是Oracle触发器中访问伪记录的强制语法,漏掉冒号就会触发ORA-00984错误。 - 多列更新处理:增加了对
NOTES列的判断,确保每一列更新时都能生成对应的审计记录。 - 完整的NULL值判断:用
OR条件覆盖了“旧值为NULL新值非NULL”、“旧值非NULL新值为NULL”的场景,避免因为NULL比较导致的漏判(因为!=无法处理NULL值的比较)。
现在你可以编译这个触发器,应该就能正常工作了!
内容的提问来源于stack exchange,提问作者Osman mohammad
相关产品推荐
相关产品推荐

