简体   繁体   English

Oracle 11g:使用自动增量long值将列添加到EXISTING表中

[英]Oracle 11g: add a column to an EXISTING table with auto increment long value

I have a table, say Name, (I simplify the example for simplicity). 我有一个表,说Name(为简单起见,我简化了示例)。 This table already exists, and has data. 该表已经存在,并且具有数据。 Now, I need to add an ID column of type long to it, and need to make the value auto incremented. 现在,我需要向其添加一个long类型的ID列,并需要使该值自动递增。

For Oracle 12c, this is easy with generated always as identity . 对于Oracle 12c,这很容易生成,始终以identity身份生成

However, I work on Oracle 11g, and such a feature is not supported. 但是,我正在使用Oracle 11g,并且不支持该功能。 So I needed to create a trigger, as described in this post: How to create id with AUTO_INCREMENT on Oracle? 因此,我需要创建一个触发器,如本博文所述: 如何在Oracle上使用AUTO_INCREMENT创建ID?

alter table name add (id integer);

create sequence name_seq;

create or replace trigger name_bir;   
before insert on name
for each row
begin
 select name_seq.NEXTVAL
 into :new.id
 from dual;
end;

However, that solution (creating a sequence, and then a trigger on Insert/Update) only works when a new row is inserted. 但是,该解决方案(创建序列,然后在“插入/更新”上创建触发器)仅在插入新行时有效。 It doesn't apply to the existing rows in the table. 它不适用于表中的现有行。

I'd appreciate any suggestion. 我将不胜感激任何建议。 Basically, I need BOTH the existing and the newly-inserted rows to have the new ID values for my newly added column ID. 基本上,我需要既有现有行又有新插入的行,以具有新添加的列ID的新ID值。

============================= ============================

Solution (collected from the answer): 解决方案(从答案中收集):

  1. Use "update" statement as posted by "a_horse_with_no_name" to update the existing rows 使用“ a_horse_with_no_name”发布的“ update”语句来更新现有行

  2. Still need a trigger above for any new rows that will be inserted. 上面仍然需要一个触发器来插入将要插入的任何新行。

After you created the sequence, just update the existing rows: 创建序列后,只需更新现有行:

alter table name add (id integer);

create sequence name_seq;

update name 
  set id = name_seq.nextval;
commit;

There is no need for PL/SQL or a slow and in-efficient row-by-row processing in a LOOP. 无需在LOOP中使用PL / SQL或效率低下的逐行处理。


Unrelated, but: the assignment in the trigger can be simplified to: 无关,但是:触发器中的分配可以简化为:

:new.id := name_seq.NEXTVAL;

No need for a select .. from dual 无需select .. from dual

在添加ID列并按照您提到的那样创建NAME_SEQ序列之后,而不是使用循环,一个更简单的选择是使用Update语句,如下所示:

update NAME set ID= NAME_SEQ.nextval ;

This should do the trick 这应该可以解决问题

BEGIN
alter table name add (id integer);
create sequence name_seq;

FOR REC IN (SELECT * FROM NAME) LOOP
UPDATE NAME SET ID = NAME_SEQ.NEXTVAL 
WHERE ROWID = REC.ROWID;
END LOOP;
END;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM