今天在写触发器的时候突然想到这一点,为了验证想法,做了一个简单的例子。
如果一个字段拥有默认值,且包含一个BEFORE的行级触发器,当不指定值时,二者的生效顺序如何:
SQL> CREATE TABLE t_trigger_default (id NUMBER, col varchar2(30) DEFAULT 'default'); TABLE created. SQL> CREATE TRIGGER t_b_tri_def 2 BEFORE INSERT ON t_trigger_default 3 FOR each ROW 4 BEGIN 5 :NEW.col := 'trigger'; 6 END; 7 / TRIGGER created. SQL> INSERT INTO t_trigger_default (id) 2 VALUES (1); 1 ROW created. SQL> SELECT * FROM t_trigger_default; ID COL ---------- ------------------------------ 1 TRIGGER SQL> CREATE OR REPLACE TRIGGER t_b_tri_def 2 BEFORE INSERT ON t_trigger_default 3 FOR each ROW 4 BEGIN 5 :NEW.col := nvl(:NEW.col, 'trigger'); 6 END; 7 / TRIGGER created. SQL> INSERT INTO t_trigger_default (id) 2 VALUES (2); 1 ROW created. SQL> SELECT * FROM t_trigger_default; ID COL ---------- ------------------------------ 1 TRIGGER 2 DEFAULT SQL> INSERT INTO t_trigger_default (id, col) 2 VALUES (3, ''); 1 ROW created. SQL> SELECT * FROM t_trigger_default; ID COL ---------- ------------------------------ 1 TRIGGER 2 DEFAULT 3 TRIGGER |
从这个例子可以看出,无论是DEFAULT值还是TRIGGER都是生效的,只不过TRIGGER在DEFAULT值之后生效。当一个列的值在插入时没有指定值,那么DEFAULT值就会生效,如果有触发器修改这个列的值,那么这个修改发生在DEFAULT值生效之后。一旦列输入了值,则DEFAULT值不再生效。
而AFTER触发器是无法修改列的值的。