将主键列添加到旧 table

Add a primary key column to an old table

所以我有一个包含 50 多行的 table。目前这个 tables 没有任何主 key/ID 列。现在,如果我必须添加一个主键列,它不允许我这样做,因为 table 中已经存在数据,因此没有唯一列或列组合。谁能建议我如何将主列添加到现有的 table 中,其中包含数据。

如果 table 由于缺少 PK 定义 出现一些重复记录,您可以逐步 恢复 .

第一步中,您禁止创建新的重复行

假设您的 PK 候选列col1, col2,如下例所示:

CREATE TABLE test_pk as
SELECT 'A' col1, 1 col2 FROM dual UNION ALL
SELECT 'A' col1, 2 col2 FROM dual UNION ALL
SELECT 'B' col1, 1 col2 FROM dual UNION ALL
SELECT 'B' col1, 1 col2 FROM dual;

无法定义 PK,因为存在重复项

ALTER table test_pk  ADD CONSTRAINT my_pk UNIQUE (col1, col2);
-- ORA-02299: cannot validate (xxx.MY_PK) - duplicate keys found

但您可以在 PK 列上创建索引,并在状态 ENABLE NOVALIDATE.

中设置约束

这将容忍 现有的重复项,但拒绝 新的一次。

CREATE INDEX my_pk_idx ON test_pk(col1, col2);

ALTER TABLE test_pk
ADD CONSTRAINT my_pk UNIQUE (col1,col2) USING INDEX my_pk_idx
ENABLE NOVALIDATE;

现在您可以插入新的唯一行...

INSERT INTO test_pk (col1, col2) VALUES ('A', 3);
-- OK

...但是您不能创建新的重复项:

INSERT INTO test_pk (col1, col2) VALUES ('A', 1);
-- ORA-00001: unique constraint (xxx.MY_PK) violated

稍后在 第二步 中,您可以决定 clenup table 和 VALIDATE 约束,这将使 完美的主键 如预期的那样:

-- cleanup
DELETE FROM TEST_PK 
WHERE col1 = 'B' AND col2 = 1 AND rownum = 1;

ALTER TABLE test_pk MODIFY CONSTRAINT my_pk ENABLE VALIDATE;

(自 12.1 起)您可以使用以下任一方式向 table 添加一个新的自动递增代理键:

alter table t
  add ( t_id integer generated by default as identity );

create sequence s;
alter table t
  add ( t_id integer default s.nextval );

这些设置了所有现有行的值。所以可能需要一段时间 tables!

不过,您还应该考虑在业务键上添加唯一约束。为此,请按照 Marmite Bomber 建议的步骤进行操作。