我想知道如何在现有的oracle表中添加标识列?我正在使用oracle 11g。假设我有一个名为DEGREE的表,我将为其添加一个标识列。
FYI表不为空。
答案 0 :(得分:6)
你无法一步到位。取而代之的是,
更改表并添加列(没有主键约束)
ALTER TABLE DEGREE ADD (Ident NUMBER(10));
使用满足主键约束(唯一/非空)的数据填充新列,例如:像
UPDATE DEGREE SET Ident=ROWNUM;
更改表格并将约束添加到列
ALTER TABLE DEGREE MODIFY (Ident PRIMARY KEY);
完成此操作后,您可以设置SEQUENCE
和BEFORE INSERT
触发器来自动设置新记录的ID值。
答案 1 :(得分:3)
添加列
alter table table_name add (id INTEGER);
使用table_name_id_seq
子句创建序列start with
,使用表格中的行数+ 1或其他安全值(我们不想要重复的ID);
锁定表格(无插入)
alter table table_name lock exclusive mode;
填写专栏
update table_name set id = rownum; --or another logic
添加触发器以使用序列自动将id插入插入内容(您可以在互联网上找到示例,例如this answer)
当您触发创建触发器时,锁定将被释放。 (它会自动提交)。 此外,您可以在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 列不是自动递增的