Oracle重置序列發生器(非重建)

1、背景

1.1 背景

項目中有5個序列發生器(分別爲:seq1、seq2、seq3、seq4、seq5),各序列發生的作用是產生[10000,19999)、[20000,29999)、[30000,39999)、[40000,49999)、[50000,59999)的數值。創建序列的DDL如下:

CREATE SEQUENCE seq1
  START WITH 10001
  MAXVALUE 999999999999999999999999999
  MINVALUE 10001
  increment by 1
  NOCYCLE
  NOCACHE
  ORDER;

其他的同樣,區別只是開始值不同

1.2 問題

目前每天晚上00:00有定時任務,作用是刪掉序列發生器,然後重建,保證每天的序列發生器是從起始值開始的。

最近一段時間偶爾出問題,經查詢,重置序列發生器的定時任務在運行時,有其他定時任務正在使用這些序列發生器,從而導致定時任務失敗。

因此,現場要求:既要重置序列發生器,又避免發生異常。

所以,採用非重建的方式重置序列發生器

2、解決方案

創建procedure,如下:

/*
  創建人:鄭林 2017-8-30
  方法說明:重置序列發生器
  參數說明:v_seqname序列發生器名稱;v_standard序列的起始號碼
*/
create or replace procedure seq_reset(v_seqname varchar2,v_standard number) as
  n    number(10);
  tsql varchar2(100);
  begin
       --獲取序列的當前值
       execute immediate 'select '|| v_seqname ||'.nextval from dual' into n;
       n :=v_standard-(n-1);
       --更改步長
       tsql := 'alter sequence '|| v_seqname ||' increment by ' || n;
       execute immediate tsql;
       
       --獲取當前值
       begin
               execute immediate 'select '|| v_seqname ||'.nextval from dual' into n;
       exception                
               when others then
                 if sqlcode='-8004' then
                    tsql:='alter sequence '||v_seqname||' increment by 1';
                    execute immediate tsql;
                 end if;
       end; 
       
       --恢復步長
       tsql := 'alter sequence ' || v_seqname ||' increment by 1';
       execute immediate tsql;
  
end seq_reset;

參數中v_standard爲起始值。

這樣,重寫定時任務,便可解決當前問題

exec seq_reset('seq1',1000);

3、參考資料

1、動態SQL,參考:動態SQL資料鏈接

2、非重建方式,參考:非重建的鏈接



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章