我在创建触发器时遇到问题。
create table dwarfs (
name varchar2(20),
nickname varchar2(20),
note varchar2(20),
primary key (name,nickname)
);
思想: 当有人想要插入数据而不输入名称触发器时,应添加默认名称,例如“Dwarf1”
我创建了触发器,但是我得到了
communicate:SQL Error: ORA-01400: cannot insert NULL into
01400. 00000 - "cannot insert NULL into (%s)"
create or replace trigger t_d
before insert or update on dwarfs
for each row
when (new.name=null or new.name= '')
declare
begin
:new.name:='Dwarf1';
end;
答案 0 :(得分:0)
正如@kodirko在他的评论中指出的那样,比较(new.name=null or new.name='')
永远不会起作用,因为与NULL的比较总是返回NULL,而不是TRUE或FALSE。要确定列是否为NULL,您需要使用特殊比较构造IS NULL
。另请注意,因为nickname
是主键的一部分,所以它也必须永远不会为NULL - 所以,当你把它们放在一起时,你可能会尝试重写你的触发器:
create or replace trigger t_d
before insert or update on dwarfs
for each row
when (new.name IS NULL OR NEW.NICKNAME IS NULL)
begin
IF :new.NAME IS NULL THEN
:new.NAME := 'Dwarf1';
END IF;
IF :new.NICKNAME IS NULL THEN
:new.NICKNAME := :new.NAME;
END IF;
end;
分享并享受。
答案 1 :(得分:0)
这是一个没有看到树林的典型案例。是的,在=
的测试中使用null
的技术细节。然而,重点是......
永远不要将关键领域的默认值分配给关键领域!!!
如果一个字段是一个关键字段,那么没有它就明显无法使用元组。如果缺少该数据,则会出现非常非常错误的情况,并且应该不惜一切代价阻止该行的其余部分插入数据库。
当然,这不适用于定义为代理键的身份或自动生成值。根据定义,代理键完全独立于实体数据。 (这指出了代理键的缺点,但这是一个不同的讨论。)这仅适用于已进一步标识为关键字段的属性字段。
如果缺少值并且未提供默认值,则任何插入行的尝试都将生成错误。这正是你想要发生的事情。不要让用户容易破坏数据库的完整性。