我之前从未在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
答案 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块,该块对非空值不执行任何操作。