Oracle触发器创建自动编号

时间:2011-11-30 17:31:22

标签: oracle plsql triggers

我之前从未在Oracle中创建过触发器,因此我正在寻找一些方向。

如果ID不在insert语句中,我想创建一个将ID递增1的触发器。

ID应该从10000开始,当插入记录时,下一个ID应该是10001.如果insert语句包含ID,它应该覆盖自动增量。

insert into t1 (firstname, lastname) values ('Michael','Jordan'),('Larry','Bird')

应该是这样的:

firstname lastname id

Micahel Jordan 10000

Larry Bird 10001

insert into t1 (firstname, lastname, id) values ('Scottie','Pippen',50000)

应该是这样的:

firstname lastname id

Micahel Jordan 10000

Larry Bird 10001

Scottie Pippen 50000

2 个答案:

答案 0 :(得分:25)

这样的东西适用于11g

CREATE SEQUENCE t1_id_seq 
  start with 10000 
  increment by 1;

CREATE TRIGGER trigger_name
  BEFORE INSERT ON t1
  FOR EACH ROW
DECLARE
BEGIN
  IF( :new.id IS NULL )
  THEN
    :new.id := t1_id_seq.nextval;
  END IF;
END;

如果您使用的是早期版本,则需要执行SELECT INTO以获取序列中的下一个值

CREATE TRIGGER trigger_name
  BEFORE INSERT ON t1
  FOR EACH ROW
DECLARE
BEGIN
  IF( :new.id IS NULL )
  THEN
    SELECT t1_id_seq.nextval
      INTO :new.id
      FROM dual;
  END IF;
END;

请注意,Oracle序列不是无间隙的。因此,出于各种原因,完全有可能跳过特定值。您的第一个插入可能具有10000的ID,如果它在几分钟,几小时或几天后完成,则第二个插入的ID可能为10020。

此外,请注意Oracle不支持像MySQL那样在VALUES子句中指定多行。所以而不是

insert into t1 (firstname, lastname) values ('Michael','Jordan'),('Larry','Bird')

你需要两个单独的INSERT语句

insert into t1 (firstname, lastname) values ('Michael','Jordan');
insert into t1 (firstname, lastname) values ('Larry','Bird');

答案 1 :(得分:3)

我建议使用触发器本身的条件来编码此触发器,而不是在sql块中。

CREATE OR REPLACE TRIGGER your_trigger
BEFORE INSERT ON your_table
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
WHEN (new.id IS NULL)
  BEGIN
    SELECT your_sequence.nextval
    INTO :new.id
    FROM dual;
  END;
/

使用此解决方案,仅在条件匹配时执行触发器(id为null)。

否则,始终执行触发器,并且块检查id是否为null。 DB必须执行SQL块,该块对非空值不执行任何操作。