【发布时间】:2016-07-14 05:09:29
【问题描述】:
我创建了一个插入/更新前触发器,如下所示
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_by 值与登录用户而不是操作系统用户相同,如果 last_modified_by 为空,则获取操作系统用户 ID。当我从 UI 更新此表时,它工作正常。最后按值修改的值是以登录用户 ID 的形式出现的(因为它是在更新语句中传递的)。
但是当我从 sql developer 更新 AUDIT_TABLE 中的其他列时, :new.last_modified_by 永远不会出现 null 而是它的值与 :old.last_modified_by 相同时间>
Que1- 我处理这种情况的方式不如
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 触发器的标准行为吗?
【问题讨论】:
-
new variables have old values if they are not changed while updating...如果旧值和新值相同,那么这不就是您在逻辑上所期望的吗? -
如果我没有更改列值,我期待 :new .column 为空,因为它不在上下文中,或者我没有将任何东西作为新值传递..但看起来我错过了这个写触发器时。
-
:new.LAST_MODIFIED_BY = NULL可能不会产生想要的结果,所以正确的写法是:new.LAST_MODIFIED_BY is NULL。根据我过去的经验,与val is NULL(或val is NOT NULL)相比,val = NULL的可靠性较低。 -
感谢安贾恩。我会这样做的。
-
不相关,但是:您知道
OS_USER是客户端应用程序 提供的信息。我可以使用Krishnat Molawade作为操作系统用户名连接到任何Oracle 服务器。不要依赖它!