将主键列添加到旧 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 建议的步骤进行操作。
所以我有一个包含 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 建议的步骤进行操作。