小编典典

将Oracle序列重置为现有列中的下一个值的最佳方法?

sql

由于某些原因,过去的人们在不使用sequence.NEXTVAL的情况下插入了数据。因此,当我使用sequence.NEXTVAL填充表时,我遇到了PK冲突,因为该数字已在表中使用。

如何更新下一个值以使其可用?现在,我只是一遍又一遍地插入,直到成功(INSERT INTO tbl (pk) VALUES (sequence.NEXTVAL)),然后同步nextval。


阅读 191

收藏
2021-03-17

共1个答案

小编典典

这两个过程让我重置序列并根据表中的数据重置序列(为此客户端使用的编码约定致歉):

CREATE OR REPLACE PROCEDURE SET_SEQ_TO(p_name IN VARCHAR2, p_val IN NUMBER)
AS
   l_num   NUMBER;
BEGIN
   EXECUTE IMMEDIATE 'select ' || p_name || '.nextval from dual' INTO l_num;

   -- Added check for 0 to avoid "ORA-04002: INCREMENT must be a non-zero integer"
   IF (p_val - l_num - 1) != 0
   THEN
      EXECUTE IMMEDIATE 'alter sequence ' || p_name || ' increment by ' || (p_val - l_num - 1) || ' minvalue 0';
   END IF;

   EXECUTE IMMEDIATE 'select ' || p_name || '.nextval from dual' INTO l_num;

   EXECUTE IMMEDIATE 'alter sequence ' || p_name || ' increment by 1 ';

   DBMS_OUTPUT.put_line('Sequence ' || p_name || ' is now at ' || p_val);
END;

CREATE OR REPLACE PROCEDURE SET_SEQ_TO_DATA(seq_name IN VARCHAR2, table_name IN VARCHAR2, col_name IN VARCHAR2)
AS
   nextnum   NUMBER;
BEGIN
   EXECUTE IMMEDIATE 'SELECT MAX(' || col_name || ') + 1 AS n FROM ' || table_name INTO nextnum;

   SET_SEQ_TO(seq_name, nextnum);
END;
2021-03-17