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、非重建方式,參考:非重建的鏈接