序列本身不能实现此类功能,序列需要重建才能重新从1开始取
你的这个需求可以使用两个序列,配合oracle定时任务进行实现1、创建两个序列,假设为A、B
2、第一天使用序列A,到第二天使用序列B,利用定时任务重建A,第三天再使用序列A,利用定时任务重建B,如此往复

解决方案 »

  1.   

    创建一个job,每天凌晨的时候定时执行,job的功能是将序列重置。
    对序列先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;//还原 
      

  2.   

    创建一个job,每天凌晨的时候定时执行,job的功能是将序列重置。
    对序列先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;//还原 
    这个要看实际业务的数据量,是否允许你有这么一个时间去重置序列,对于大业务量的数据,即使是毫秒级的时间都可能产生问题数据,根据自己的业务量选择适合的方式吧
      

  3.   

    不知道楼主这种实现,要勇于什么场景不能用主键ID替代?主键ID完成所述实现,更有可能
      

  4.   

    就是一个很小的功能、在新建单据时单号用当前日期yyyyMMdd+3位流水号,每天都从001开始;
    如果用job是不是有点麻烦!
    自定义函数?....在后台代码中我可以处理!但不能保证数据很好的同步,比方说有个人在新建单时
    我可以产生一个yyyyMMdd+001的单据号;但如果这个时候、另外一个人也在他后面一点点时间建单、获取的单号任然是yyyyMMdd+001;在这个时候,就看谁先提交了、先提交的那个人的单号就是正确的、而后提交的那个这个时候也已yyyyMMdd+001提交时,就会和第一个人的单据号重复!
    就是数据的同步性很不安全.
      

  5.   

    job实现起来还是很简单的,创建定时任务都是固定的代码
    目前能想到的方式,也就是两个序列配合定时任务实现,比较稳妥
    其他的方式都存在漏洞
    1、单个序列,晚上0时清0或重建,这个在执行清零或重建的过程时,容易产生错误数据
    2、不用序列,使用最大号+1的方式获取
    在最后提交的时候重新获取编号,能有效的减少重码几率,但是再怎么弄也不能100%的避免
      

  6.   

    你这个需求用序列确实不好控制
    为什么每天都要001开始,yyyyMMdd+序列 不是挺好的吗?
      

  7.   

    真想不出有啥难的,一共都没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;