2009-09-04 30 views
4

在Oracle中編寫行級觸發器時,我知道您可以使用OLDNEW僞記錄來引用觸發觸發器的行的新舊狀態。
我知道在INSERT觸發器OLD不包含任何數據,但我不知道這是如何影響該觸發器的WHEN子句的評估。舉例來說,如果我有以下觸發:OLD引用在Oracle插入觸發器的WHEN原因中評估什麼?

CREATE OR REPLACE TRIGGER mung_row 
BEFORE INSERT OR UPDATE ON some_table 
FOR EACH ROW 
BEGIN 
    :NEW.foo = 'some val'; 
END; 

,我想修改該觸發器僅在更新時富先前空運行,但總是在插入跑,我能滿足的更新部分在插入的情況下

CREATE OR REPLACE TRIGGER mung_row 
BEFORE INSERT OR UPDATE ON some_table 
FOR EACH ROW 
WHEN (OLD.foo IS NULL) 
BEGIN 
    :NEW.foo = 'some val'; 
END; 

這會帶來問題:通過添加WHERE條款的變化? OLD.foo將在INSERT中評估什麼?

我知道,我可能分裂INSERTUPDATE觸發器或觸發器主體使用INSERTING/UPDATING/DELETING,但我寧願沒有啓發這個問題的情況。

回答

9

插入記錄時,OLD的每個字段將爲NULL,包括表定義中標記爲NOT NULL的字段。

例如,假設你的表有一個名爲id非空列:

CREATE TABLE some_table (
    id NUMBER NOT NULL, 
    foo VARCHAR2(100) 
) 

當一條記錄被插入到這個表中,OLD.idNULL。但是,當此表中的記錄更新時,OLD.id將不是NULL。因爲如果記錄正在更新,您只想更改:NEW.foo,您只需檢查OLD.id是否具有非空值。

CREATE OR REPLACE TRIGGER mung_row 
BEFORE INSERT OR UPDATE ON some_table 
FOR EACH ROW 
WHEN (OLD.id IS NOT NULL AND OLD.foo IS NULL) 
BEGIN 
    :NEW.foo = 'some val'; 
END;