oracle新增ID主键列,如何补全旧数据的ID值
1.创建SEQUENCE
CREATE SEQUENCE MONKEY.TEST_ADD_IDCOL_ID CACHE 100;
2.新增表栏位
ALTER TABLE MONKEY.TEST_ADD_IDCOL ADD(ID NUMBER);
3.重新编译USEDBY
4.创建trigger
CREATE TRIGGER MONKEY.TRI_TEST_ADD_IDCOL BEFORE INSERT ON MONKEY.TEST_ADD_IDCOL FOR EACH ROW BEGIN SELECT MONKEY.TEST_ADD_IDCOL_ID.NEXTVAL INTO :NEW.ID FROM DUAL; END;
5.补数据
/* Formatted on 2020/5/11 下午 02:00:49 (QP5 v5.163.1008.3004) */ DECLARE CURSOR ROWIDS IS SELECT ROWIDTOCHAR (ROWID) AS RID FROM MONKEY.TEST_ADD_IDCOL WHERE ID IS NULL; V_COUNT NUMBER := 0; BEGIN FOR R IN ROWIDS LOOP UPDATE MONKEY.TEST_ADD_IDCOL SET ID = MONKEY.TEST_ADD_IDCOL_ID.NEXTVAL WHERE ROWID = R.RID; V_COUNT := V_COUNT + 1; IF V_COUNT = 1000 THEN COMMIT; V_COUNT := 0; END IF; END LOOP; COMMIT; END;
通过ROWID确定到每一行,防止重复插入,同时,每一千行提交一笔,对大表比较友好,防止过大的UNDO产生以及失败后的长时间回滚
如果是小表(小于1G),可以使用如下方法
/* Formatted on 2020/5/11 下午 02:09:42 (QP5 v5.163.1008.3004) */ UPDATE MONKEY.TEST_ADD_IDCOL SET ID = MONKEY.TEST_ADD_IDCOL_ID.NEXTVAL WHERE ID IS NULL;
不管使用哪种方法,都需要查出来ID是NULL的行,索引是不存放NULL值的,因此在查找NULL值的过程中,无法使用索引,为解决这个问题,可以使用联合索引
CREATE INDEX MONKEY.IX_TEST_ADD_IDCOL ON MONKEY.TEST_ADD_IDCOL (ID,0) ONLINE;
ONLINE可以不妨碍现有业务,和0联合就可以在查找NULL过程中用索引
6.修改ID为主键
ALTER TABLE MONKEY.TEST_ADD_IDCOL ADD(CONSTRAINT PK_TEST_ADD_IDCOL PRIMARY KEY(ID));