Oracle 触发器创建自动编号
Posted
技术标签:
【中文标题】Oracle 触发器创建自动编号【英文标题】:Oracle trigger to create an autonumber 【发布时间】:2012-01-09 22:42:43 【问题描述】:我之前从未在 Oracle 中创建过触发器,所以我正在寻找方向。
我想创建一个触发器,如果 ID 不在插入语句中,则将 ID 加一。
ID 应该从 10000 开始,当插入一条记录时,下一个 ID 应该是 10001。如果插入语句包含一个 ID,它应该覆盖自动增量。
即
insert into t1 (firstname, lastname) values ('Michael','Jordan'),('Larry','Bird')
应该看起来像:
名字姓氏ID
迈克尔·乔丹 10000
拉里伯德 10001
insert into t1 (firstname, lastname, id) values ('Scottie','Pippen',50000)
应该看起来像:
名字姓氏ID
迈克尔·乔丹 10000
拉里伯德 10001
斯科蒂·皮蓬 50000
【问题讨论】:
【参考方案1】:我建议使用触发器本身的条件编写此触发器,而不是在 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 为空)时才会执行触发器。
否则触发器总是被执行并且块检查 id 是否为空。 DB 必须执行对非空值不执行任何操作的 SQL 块。
【讨论】:
【参考方案2】:这样的东西可以在 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 序列不是无间隙的。因此,出于各种原因,完全有可能跳过特定的值。如果在几分钟、几小时或几天后完成,您的第一个插入的 ID 可能为 10000,第二个插入的 ID 可能为 10020。
另外,请注意,Oracle 不支持在 VALUES 子句中指定多行,就像 mysql 那样。所以而不是
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');
【讨论】:
https://github.com/miklagard/oracle-table-creator以上是关于Oracle 触发器创建自动编号的主要内容,如果未能解决你的问题,请参考以下文章