Oracle 11主键生成

时间:2019-05-07 15:26:57

标签: oracle

我们有一个数据库表foo,

ID  NUMBER(10,0)    No      1   

其中ID是主键。

有人写了一条插入语句

INSERT INTO foo (ID, ...) VALUES (foo_squ.NEXTVAL, ...)

其中foo_squ是squense。定义如下:

 CREATE SEQUENCE  "FOO_SQU"  MINVALUE 0 MAXVALUE 9999999999 INCREMENT BY 1 START WITH 3331 NOCACHE  NOORDER  CYCLE ;

insert语句导致重复的主键错误。

要找出问题所在,我运行

select foo_squ.nextval from dual;

我得到339。我奔跑

select id from foo where id >= 338;

我得到338。

我创建了一个触发器来解决问题。

create or replace TRIGGER FOO_TRIGGER 
BEFORE INSERT ON foo FOR EACH ROW
BEGIN
  SELECT FOO_SQU.NEXTVAL
  INTO :NEW.ID
  FROM DUAL;
END;

使用触发器,ID字段不必在插入语句中。那将解决问题。但是,有人说触发器会导致性能问题。

什么是替代解决方案?

更新:

表中有一个时间戳。我们决定使用ID和时间戳的复合键来解决该问题。处理这个问题对我来说很奇怪。

1 个答案:

答案 0 :(得分:0)

我相信您应该检查该值是否不再传递,因为正如您提到的,应用程序执行命令FOO_SQU.NEXTVAL且不增加其序列两次,可以添加一个if。

create or replace TRIGGER FOO_TRIGGER 
BEFORE INSERT ON foo FOR EACH ROW
BEGIN

  IF :NEW.ID is NULL THEN
     SELECT FOO_SQU.NEXTVAL
     INTO :NEW.ID
     FROM DUAL;
  END IF;

END;

如评论中所述,在Oracle中,您几乎不会迷失顺序,可能是应用程序使用了错误的代码。

您将序列用作插入或使用触发器的参数,我相信您不会看到任何实际的差异。