有没有一种方法可以将 Oracle 中每个 table 的序列的 last_number 字段设置为该 table 的主键的最大值?

Is there a way where I can set last_number field of sequence of each table in Oracle to the maximum value of the primary key of that table?

有没有一种方法可以使用存储过程将 Oracle 中每个 table 的序列的 last_number 字段设置为该 table 的主键的最大值?

当前序列和主键的最大值之间存在一些数据不匹配,所以我试图重置序列以匹配主键的最大值,以便它正确递增。我希望通过存储过程来完成,并且有很多 table,所以我无法手动一一编辑它们。任何帮助将不胜感激!

我不知道查询的预期结果是什么,但您可以使用以下查询来获取主键列中的最大数字,如下所示:

SELECT
    C.TABLE_NAME,
    CC.COLUMN_NAME,
    to_number(xmlquery('/ROWSET/ROW/C/text()'
        passing xmltype(dbms_xmlgen.getxml(
          'select MAX( "' || CC.column_name || '") as c '
          || 'from "' || C.table_name || '"'))
    returning content)) as c
FROM
    USER_CONSTRAINTS C
    JOIN USER_CONS_COLUMNS CC ON C.CONSTRAINT_NAME = CC.CONSTRAINT_NAME
    JOIN USER_TAB_COLUMNS TC ON TC.COLUMN_NAME = CC.COLUMN_NAME
                                AND TC.TABLE_NAME = C.TABLE_NAME
WHERE
    C.CONSTRAINT_TYPE = 'P'
    AND CC.POSITION = 1
    AND TC.DATA_TYPE = 'NUMBER'
--AND C.TABLE_NAME IN ()
ORDER BY C DESC NULLS LAST;

干杯!!

假设您有一个名为 tab 的 table:

SQL> create table tab ( id int primary key );

并将主键 (id) 列填充到 10 :

SQL> insert into tab select level from dual connect by level <= 10;

例如id 的最大值为 10 并且您想将序列(如果尚不存在则创建)设置为 10 :

SQL> create or replace procedure pr_alter_seq is
  nmr tab.id%type;
  ext pls_integer := 0;
begin
  select max(id) into nmr from tab;
  begin
     select 1 into ext from user_sequences s where regexp_like(sequence_name,'myseq','i');
   exception when no_data_found then ext := 0;
  end;
  if ext = 0 then
     execute immediate 'create sequence myseq';
  end if;
     execute immediate 'alter sequence myseq increment by '||nmr;
     execute immediate 'select myseq.nextval from dual' into nmr;
     execute immediate 'alter sequence myseq increment by 1';
end;
/
SQL> exec pr_alter_seq;

Demo