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

Ali*_*i n 7 database oracle identity

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

FYI表不为空.

And*_*ter 6

你不能一步到位.代替,

完成后,您可以设置a SEQUENCEBEFORE INSERT触发器来自动设置新记录的id值.

  • 创建序列时需要使用 `start with` 匹配从 `rownum` 手动设置的最高值,而不是默认值 1;否则,当您第一次插入新行时,您会遇到约束违规。 (2认同)

Wil*_*son 5

从 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;
Run Code Online (Sandbox Code Playgroud)

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

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

update demo set demo_id = rownum;
Run Code Online (Sandbox Code Playgroud)

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

alter table demo modify demo_id generated always as identity start with limit value;
Run Code Online (Sandbox Code Playgroud)

并将其定义为主键:

alter table demo add constraint demo_pk primary key (demo_id);
Run Code Online (Sandbox Code Playgroud)

这会将新列留在列列表的末尾,这通常无关紧要(除了具有大量列和行链接问题的表),但是当您描述该表时,它看起来很奇怪。但是,我们至少可以使用 invisible/visible hack 整理字典顺序:

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
Run Code Online (Sandbox Code Playgroud)

您不能做的一件事(从 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 
Run Code Online (Sandbox Code Playgroud)