Oracle - 修改现有表以自动递增列

5

我有一张包含以下列的表格:

NOTEID      NUMBER NOT NULL,

实际上,这一栏是主键。该表有几千行,每行都有唯一的ID。以前,应用程序会从表中选择MAX()值,然后加1,然后将其用作下一个值。这是一个可怕的解决方案,不是事务或线程安全的(实际上,在此之前,他们甚至没有在列上有UNIQUE约束,并且我看到相同的NOTEID在9个不同的场合被复制)。
我对Oracle比较新,所以我想知道最佳的语法来更改此表并使此列自动增量。如果可能的话,我想让序列中的下一个值为表中的MAX(NOTEID)+ 1,或者只是从800开始。谢谢!
2个回答

14

你无法修改表。Oracle不支持声明式自增列。你可以创建一个序列。

CREATE SEQUENCE note_seq
  START WITH 800
  INCREMENT BY 1
  CACHE 100;

然后,你可以创建一个触发器

CREATE OR REPLACE TRIGGER populate_note_id
  BEFORE INSERT ON note
  FOR EACH ROW
BEGIN
  :new.note_id := note_seq.nextval;
END;

或者,如果你想允许调用者指定非默认的NOTE_ID

CREATE OR REPLACE TRIGGER populate_note_id
  BEFORE INSERT ON note
  FOR EACH ROW
BEGIN
  IF( :new.note_id is null )
  THEN 
    :new.note_id := note_seq.nextval;
  END IF;
END;

感谢您提供详细的答案!我将接受roartechs的答案,因为您已经有了30,000个赞 :) - Mike Christensen
1
哈哈哈哈,这很有趣。现在我们就是这样接受答案的吗?可怜那些声望较低的人?谢谢! - roartechs
好的,你的回答是第一个并且从技术上满足了我的问题 :) 我想在过去几周里,在各种Oracle问题上我已经接受了Justin的大约20个答案。 - Mike Christensen

7
如果您的MAX(noteid)为799,则尝试以下操作:

CREATE SEQUENCE noteseq
    START WITH 800
    INCREMENT BY 1

在插入新记录时,对于NOTEID列,您需要执行以下操作:

noteseq.nextval

如果没有指定,是否可以将列默认为序列中的下一个值? - Mike Christensen
@Mike - 你可以在表上创建一个触发器来实现这个逻辑,当然。 - Justin Cave
明白了 - 所以它不像Postgres那样可以将其设置为默认值,或者像mySQL那样具有递增值的“SERIAL”列类型。 - Mike Christensen
1
没错,在 PostgreSQL 中没有像 MySQL 那样指定默认增量值的方法。 - roartechs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接