如果在更新触发之前未在oracle中传递更新,则新值与旧值相同

如果在更新触发之前未在oracle中传递更新,则新值与旧值相同,oracle,triggers,Oracle,Triggers,我创建了一个before insert/update触发器,如下所示 CREATE OR REPLACE TRIGGER "AUDIT_TABLE_TRIG" BEFORE INSERT OR UPDATE ON AUDIT_TABLE FOR EACH ROW BEGIN :NEW.LAST_MODIFIED_DATE:=SYSDATE; IF :new.LAST_MODIFIED_BY = NULL THEN :NEW.LAST_MODIFIED_BY :=SYS_CONTE

我创建了一个before insert/update触发器,如下所示

CREATE OR REPLACE TRIGGER "AUDIT_TABLE_TRIG" BEFORE
  INSERT OR UPDATE ON AUDIT_TABLE FOR EACH ROW BEGIN :NEW.LAST_MODIFIED_DATE:=SYSDATE;
  IF :new.LAST_MODIFIED_BY = NULL THEN
    :NEW.LAST_MODIFIED_BY :=SYS_CONTEXT('USERENV','OS_USER');
  END IF;
END;
要求更新last_modified_的值与登录用户相同,而不是OS用户,如果last_modified_by为空,则采用OS用户id。当我从UI更新此表时,它工作正常。最后一个modified by值作为登录用户id出现(在update语句中传递时)。 但当我从sql developer更新AUDIT_表中的其他一些列时,:new.last_modified_by永远不会为空,而是它的值与:old.last_modified_by

问题1-我处理这种情况的方式不如

 IF :new.LAST_MODIFIED_BY = NULL || :OLD.LAST_MODIFIED_BY !=SYS_CONTEXT('USERENV','OS_USER') THEN
            :NEW.LAST_MODIFIED_BY :=SYS_CONTEXT('USERENV','OS_USER');
 END IF;
我还有别的好办法吗

问题2:
我遇到了这种情况,我很惊讶。oracle触发器的标准行为是,如果在更新时新变量的值未更改,则新变量将具有旧值吗

尝试使用更新谓词,这可能会满足您的要求

CREATE OR REPLACE TRIGGER "AUDIT_TABLE_TRIG" BEFORE
  INSERT OR UPDATE ON AUDIT_TABLE FOR EACH ROW BEGIN :NEW.LAST_MODIFIED_DATE:=SYSDATE;
  IF NOT UPDATING('LAST_MODIFIED_BY') THEN
    :NEW.LAST_MODIFIED_BY :=SYS_CONTEXT('USERENV','OS_USER');
  END IF;
END;

新变量如果在更新时未更改,则它们具有旧值
。。。如果旧值和新值相同,那么这不是您在逻辑上所期望的吗?如果我不更改列值,我希望:new.column为null,因为它不在上下文中,或者我没有将任何内容作为新值传递..但似乎我在编写触发器时错过了此选项。
:new.LAST\u MODIFIED\u BY=null
可能无法生成所需的结果,因此正确的编写方法应该是
:new.LAST\u MODIFIED\u BY为null
。根据我过去的经验,
val=NULL
val为NULL
(或
val不为NULL
)更不可靠。谢谢Annjawn。我会这样做。无关,但是:您是否知道,
OS\u USER
是客户端应用程序提供的信息。我可以使用
Krishnat Molawade
作为操作系统用户名连接到任何Oracle服务器。别指望了!我还需要null条件,所以处理它时就好像不更新('LAST_MODIFIED_BY')或:NEW.LAST_MODIFIED_BY为null,然后:NEW.LAST_MODIFIED_BY:=SYS_CONTEXT('USERENV','OS_USER');如果结束;