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));

 

posted @ 2020-05-11 14:20  monkey6  阅读(701)  评论(0编辑  收藏  举报