ORA-04013,CACHE 值必须小于CYCLE值;解决方案
异常捕获:ORA-04013,CACHE 值必须小于CYCLE值
sequence 序列的基本概念: Min value 序列中最小的值 Max value 序列中最大的值 Next number 下一个产生的序列号 Increment by 步长,即每次加几 Cache size 缓存的序列个数,oracle 每次会产生这么多个数的缓存,再取值的时候就可以直接从缓存里面取出。 Cycle 是否循环,即达到最大值之后,是否从最小值重新开始。
SN sequence 这个序列的值说明: Min value=0 Max value=99999 Increment by=1 Cache size=20
PROCEDURE_SEQ 中存储过程重置序列到1的代码:
execute immediate 'select sn.nextval from dual' into seq; seq:=-(seq-1); ssql:='alter sequence sn increment by '||seq; execute immediate ssql ; execute immediate 'select sn.nextval from dual'into seq; ssql:='alter sequence sn increment by 1'; execute immediate ssql ;
代码阐述:报错时的情况:取出的下一个序列号为:52268.那么取反之后,seq=-52267.
此时执行修改序列号的操作。alter sequence sn increment by -52267
此时,下一个数是,52267-52267,为0.但是要注意,此时的Cache size为20,那么Oracle 就会产生20序列的缓存,并且,每个的步长为-52267。
此时,步长就会受到限制,Oracle官网给了个cache最大值的计算公式,MAX(CAHCE)=(CEIL (MAXVALUE – MINVALUE)) / ABS (INCREMENT),
(CEIL函数意思是,大于等于某数的最小整数。ABS 函数是取绝对值。)
那么步长最大值=序列最大值减去序列最小值然后除以CACHE值也应该是成立的,虽然计算出的结果不是很准确,但也不会差太多。
所以,此时,系统就抛出了异常:ORA-04013,CACHE 值必须小于CYCLE值
如果在此时,使用 NOCACHE不生成缓存,就不会受到限制。
故,修改代码:
execute immediate 'select sn.nextval from dual' into seq; seq:=-(seq-1); ssql:='alter sequence sn increment by '||seq||' nocache';----这里修改为在手动下降到1的时候,编辑sequence 为不产生缓存 execute immediate ssql ; execute immediate 'select sn.nextval from dual'into seq; ssql:='alter sequence sn increment by 1 cache 20';---这里重新设置sequence 的步长为1,缓存为20. execute immediate ssql ;