真想不出有啥难的,一共都没30行代码--使用此方法获取下一个序列的值 FUNCTION GetSeqValue RETURN number IS i number; v_result number; BEGIN select mod(trunc(sysdate)-to_Date('2014-01-01','yyyy-mm-dd'),2) into i from dual; if i=1 then select SEQ_A.NEXTVAL into v_result from dual; else select SEQ_B.NEXTVAL into v_result from dual; end if; return v_result END; --下面这个在数据库做成定时任务 PROCEDURE ResetSeq IS V_SeqName varchar2(100); BEGIN select decode(mod(trunc(sysdate)-to_Date('2014-01-01','yyyy-mm-dd'),2),1,'SEQ_B','SEQ_A') INTO V_SeqName from dual; EXECUTE IMMEDIATE 'DROP SEQUENCE '||V_SeqName; EXECUTE IMMEDIATE 'CREATE SEQUENCE '||V_SeqName||' increment by 1 start with 1 nocache nocycle'; END; --创建定时任务代码 VARIABLE jobno number;↙ begin DBMS_JOB.SUBMIT(:jobno, 'ResetSeq;', TRUNC(SYSDATE),'trunc(sysdate)+1'); commit; end;
对序列先drop再create会导致很多调用序列的包或者存储过程失效。
以下是网上找到的重置序列方法,你可以把它写成一个存储过程供job调用:Oracle中一般将自增sequence重置为初始1时,都是删除再重建,这种方式有很多弊端,依赖它的函数和存储过程将失效,需要重新编译。
不过还有种巧妙的方式,不用删除,利用步长参数,先查出sequence的nextval,记住,把递增改为负的这个值(反过来走),然后再改回来。
假设需要修改的序列名:seq_name
1、select seq_name.nextval from dual; //假设得到结果5656
2、alter sequence seq_name increment by -5655; //注意是-(n-1)
3、select seq_name.nextval from dual;//再查一遍,走一下,重置为1了
4、alter sequence seq_name increment by 1;//还原
对序列先drop再create会导致很多调用序列的包或者存储过程失效。
以下是网上找到的重置序列方法,你可以把它写成一个存储过程供job调用:Oracle中一般将自增sequence重置为初始1时,都是删除再重建,这种方式有很多弊端,依赖它的函数和存储过程将失效,需要重新编译。
不过还有种巧妙的方式,不用删除,利用步长参数,先查出sequence的nextval,记住,把递增改为负的这个值(反过来走),然后再改回来。
假设需要修改的序列名:seq_name
1、select seq_name.nextval from dual; //假设得到结果5656
2、alter sequence seq_name increment by -5655; //注意是-(n-1)
3、select seq_name.nextval from dual;//再查一遍,走一下,重置为1了
4、alter sequence seq_name increment by 1;//还原
这个要看实际业务的数据量,是否允许你有这么一个时间去重置序列,对于大业务量的数据,即使是毫秒级的时间都可能产生问题数据,根据自己的业务量选择适合的方式吧
如果用job是不是有点麻烦!
自定义函数?....在后台代码中我可以处理!但不能保证数据很好的同步,比方说有个人在新建单时
我可以产生一个yyyyMMdd+001的单据号;但如果这个时候、另外一个人也在他后面一点点时间建单、获取的单号任然是yyyyMMdd+001;在这个时候,就看谁先提交了、先提交的那个人的单号就是正确的、而后提交的那个这个时候也已yyyyMMdd+001提交时,就会和第一个人的单据号重复!
就是数据的同步性很不安全.
目前能想到的方式,也就是两个序列配合定时任务实现,比较稳妥
其他的方式都存在漏洞
1、单个序列,晚上0时清0或重建,这个在执行清零或重建的过程时,容易产生错误数据
2、不用序列,使用最大号+1的方式获取
在最后提交的时候重新获取编号,能有效的减少重码几率,但是再怎么弄也不能100%的避免
为什么每天都要001开始,yyyyMMdd+序列 不是挺好的吗?
FUNCTION GetSeqValue RETURN number IS
i number;
v_result number;
BEGIN
select mod(trunc(sysdate)-to_Date('2014-01-01','yyyy-mm-dd'),2) into i from dual;
if i=1 then
select SEQ_A.NEXTVAL into v_result from dual;
else
select SEQ_B.NEXTVAL into v_result from dual;
end if;
return v_result
END;
--下面这个在数据库做成定时任务
PROCEDURE ResetSeq IS
V_SeqName varchar2(100);
BEGIN
select decode(mod(trunc(sysdate)-to_Date('2014-01-01','yyyy-mm-dd'),2),1,'SEQ_B','SEQ_A')
INTO V_SeqName from dual;
EXECUTE IMMEDIATE 'DROP SEQUENCE '||V_SeqName;
EXECUTE IMMEDIATE 'CREATE SEQUENCE '||V_SeqName||' increment by 1 start with 1 nocache nocycle';
END;
--创建定时任务代码
VARIABLE jobno number;↙
begin
DBMS_JOB.SUBMIT(:jobno,
'ResetSeq;',
TRUNC(SYSDATE),'trunc(sysdate)+1');
commit;
end;