将自动增量标识添加到oracle中非空的现有表中

时间:2014-04-16 07:39:13

标签: database oracle identity

我想知道如何在现有的oracle表中添加标识列?我正在使用oracle 11g。假设我有一个名为DEGREE的表,我将为其添加一个标识列。

FYI表不为空。

4 个答案:

答案 0 :(得分:6)

你无法一步到位。取而代之的是,

  • 更改表并添加列(没有主键约束)

    ALTER TABLE DEGREE ADD (Ident NUMBER(10));
    
  • 使用满足主键约束(唯一/非空)的数据填充新列,例如:像

    UPDATE DEGREE SET Ident=ROWNUM;
    
  • 更改表格并将约束添加到列

    ALTER TABLE DEGREE MODIFY (Ident PRIMARY KEY);
    

完成此操作后,您可以设置SEQUENCEBEFORE INSERT触发器来自动设置新记录的ID值。

答案 1 :(得分:3)

  1. 添加列

    alter table table_name add (id INTEGER);

  2. 使用table_name_id_seq子句创建序列start with,使用表格中的行数+ 1或其他安全值(我们不想要重复的ID);

  3. 锁定表格(无插入)

    alter table table_name lock exclusive mode;

  4. 填写专栏

    update table_name set id = rownum; --or another logic

  5. 添加触发器以使用序列自动将id插入插入内容(您可以在互联网上找到示例,例如this answer

  6. 当您触发创建触发器时,锁定将被释放。 (它会自动提交)。 此外,您可以在id列上添加唯一约束,最好这样做。

答案 2 :(得分:1)

从Oracle 12c开始,您将使用标识列。

例如,假设您的表名为demo,并且有3列和100行:

create table demo (col1, col2, col3)
as
select dbms_random.value(1,10), dbms_random.value(1,10), dbms_random.value(1,10)
from   dual connect by rownum <= 100;

您可以使用以下方式添加标识列:

alter table demo add demo_id integer generated by default on null as identity;

update demo set demo_id = rownum;

然后重置内部序列以匹配数据并防止手动插入:

alter table demo modify demo_id generated always as identity start with limit value;

并将其定义为主键:

alter table demo add constraint demo_pk primary key (demo_id);

这会将新列保留在列列表的末尾,这通常不重要(除了具有大量列和行链接问题的表),但在描述表时看起来很奇怪。但是,我们至少可以使用隐形/可见黑客来整理字典顺序:

SQL> desc demo
 Name                             Null?    Type
 -------------------------------- -------- ----------------------
 COL1                                      NUMBER
 COL2                                      NUMBER
 COL3                                      NUMBER
 DEMO_ID                          NOT NULL NUMBER(38)

begin
    for r in (
        select column_name from user_tab_columns c
        where  c.table_name = 'DEMO'
        and    c.column_name <> 'DEMO_ID'
        order by c.column_id
    )
    loop
        execute immediate 'alter table demo modify '||r.column_name||' invisible';
        execute immediate 'alter table demo modify '||r.column_name||' visible';
    end loop;
end;
/

SQL> desc demo
 Name                             Null?    Type
 -------------------------------- -------- ----------------------
 DEMO_ID                          NOT NULL NUMBER(38)
 COL1                                      NUMBER
 COL2                                      NUMBER
 COL3                                      NUMBER

您可以做的一件事(从Oracle 18.0开始)是改变现有列以使其成为标识列,因此您必须经历上述过程,但复制现有值和最后删除旧列,或者使用标识列显式定义新表,并在单独的步骤中复制数据。否则你会得到:

-- DEMO_ID column exists but is currently not an identity column:
alter table demo modify demo_id generated by default on null as identity start with limit value;

-- Fails with:
ORA-30673: column to be modified is not an identity column 

答案 3 :(得分:0)

对于甲骨文:

CREATE TABLE new_table AS (SELECT ROWNUM AS id, ta.* FROM old_table ta)

记住这个 id 列不是自动递增的