如何在BEFORE INSERT触发器中找出,用户是否已为空值列显式传递NULL值,或者用户是否未传递任何值该专栏。
换句话说,我将能够做到以下几点:
create table t (id, NUMBER, str VARCHAR2(30) );
create Trigger trg
befor INSERT on t
FOR earch row
DECLARE
BEGIN
IF :NEW.str is NULL
THEN
IF <NULL-Value was explicit passed> THEN
dbms_output.put_line( 'user has passed NULL');
ELSE
dbms_output.put_line( 'user has passed nothing');
END IF;
END IF;
END;
/
然后
INSERT INTO t (id, str) VALUES (1, NULL);
我会看到
> user has passed NULL
之后
INSERT INTO t (id) VALUES (1);
我会看到
> user has passed nothing
答案 0 :(得分:4)
Oracle中没有办法以编程方式区分故意传递的NULL和默认的NULL。
除了其他任何东西之外,当NULL肯定仍然没有意义时,它会将含义归为NULL。你为什么要那样做?
@OneDay当sez:
“科德自己提出了第二种类型 NULL表示'不适用'“
是的,对于数据库,“此页面故意留空”。显然,在他生命的尽头,Codd已经确定了四种不同类型的NULL。 8-)
其他版本的RDBMS区分空字符串和NULL,也许某些地方有一个约定,空字符串意味着“不适用”,而NULL意味着什么。但是,Oracle将空字符串视为NULL,并且没有人实现Codd的NULL2。所以我认为在Oracle中将含义归为NULL是危险的。
有些数据库理论家认为NULL是Codd的重大错误之一,而且对于不同类型的NULL来说这是两倍。有关该主题的有趣替代选择,请尝试阅读Chris Date的How To Handle Missing Information Without Using NULL
答案 1 :(得分:2)
为什么要对此使用触发器,而不是表列上的默认值?根据您对APC答案的评论,这不是您想要实现的目标吗?
create table t(id number, str varchar2(32) default 'default value');
create view v as select * from t;
insert into t(id) values (1);
insert into t(id, str) values (2,null);
insert into v(id) values (3);
insert into v(id, str) values (4,null);
select * from t;
ID STR
---------------------- --------------------------------
1 default value
2
3 default value
4