触发器 - 在缺少数据时将默认值插入主键

时间:2014-11-11 19:49:02

标签: oracle plsql triggers null

我在创建触发器时遇到问题。

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;

2 个答案:

答案 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的技术细节。然而,重点是......

永远不要将关键领域的默认值分配给关键领域!!!

如果一个字段是一个关键字段,那么没有它就明显无法使用元组。如果缺少该数据,则会出现非常非常错误的情况,并且应该不惜一切代价阻止该行的其余部分插入数据库。

当然,这不适用于定义为代理键的身份或自动生成值。根据定义,代理键完全独立于实体数据。 (这指出了代理键的缺点,但这是一个不同的讨论。)这仅适用于已进一步标识为关键字段的属性字段。

如果缺少值并且未提供默认值,则任何插入行的尝试都将生成错误。这正是你想要发生的事情。不要让用户容易破坏数据库的完整性。