• 【Oracle】仿Oracle Sequence的自定义年份Sequence(适合任何数据库)(续)


    在《仿Oracle Sequence的自定义年份Sequence(适合任何数据库)》中(http://www.cnblogs.com/litou/articles/1689655.html)建立表和函数的方法模拟Sequence,效果确实不错,但还有点不足,就是需要初始化很多年份数据,尽管很少情况下用完,但何不改造成完全自动增加呢?

    自动增加的原理,就是在表中保存一条模板记录,当当前年份记录不存在时,从模板记录中复制出来并修改为当前年份,问题迎刃而解。

    原表接口和仿CurrVal函数不变(请参考上一篇文章),仿NextVal函数需要修改:

    create or replace function IDNextval return number is
      PRAGMA AUTONOMOUS_TRANSACTION; --Oracle函数中需要添加此参数才能在函数中执行SQL
      Result Number;
      lYear number;
      lCount number;
      cursor idsequence_cursor(nYear in varchar2) is select * from idsequence where year=nYear;
      refidsequence idsequence_cursor%rowtype;
    begin
      lYear := to_char(sysdate, 'yyyy');
      Result := -1;
    
      --当前年份无记录,从year=0模板复制
      select count(1) into lCount from idsequence where year=lYear;
      if lCount = 0 then
        select count(1) into lCount from idsequence where year=0;
        if lCount = 1 then
          insert into idsequence(year, minvalue, maxvalue, nextnumber, increaseby, cycle) select lYear, minvalue, maxvalue, nextnumber, increaseby, cycle from idsequence where year=0;
          commit;
        end if;
      end if;  
    
      --获取值
      open idsequence_cursor(lYear);
      fetch idsequence_cursor into refidsequence;
      if idsequence_cursor%found then
        Result := refidsequence.nextnumber;
        if refidsequence.nextnumber >= refidsequence.minvalue then --当前值大于等于最小值
          if refidsequence.nextnumber >= refidsequence.maxvalue then --当前值大于等于最大值
            if refidsequence.cycle = 1 then --循环则当前值等于最小值
              update idsequence set nextnumber=minvalue where year=lYear;
            else --不循环则当前值为最小值-1,即无效值
              update idsequence set nextnumber=minvalue-1 where year=lYear;
            end if;
          else --当前值大于等于最小值小于最大值
            if refidsequence.nextnumber+refidsequence.increaseby > refidsequence.maxvalue then --当前值加增量大于最大值
              update idsequence set nextnumber=minvalue where year=lYear;
            else
              update idsequence set nextnumber=nextnumber+refidsequence.increaseby where year=lYear;
            end if;
          end if;
          commit;
        end if;
      end if;
      close idsequence_cursor;
    
      return(Result);
    end IDNextval;
    

    这里指定了year为0的记录为模板记录,可根据实际情况修改。

    后话:自定义Sequence确实很方便,以上方法只是抛砖引肉,还可以进行改造和深化,如可在表中添加字段Type,就可以为所有类似方式的年份流水号公用一个表,不必每种流水号都要建表盒函数;甚至还可以根据实际情况添加字段,把所有的复合流水号管理起来。到那个时候要注意一点,必须建好索引。

  • 相关阅读:
    securefile allocation chunks
    脚本:Segment Space Usage Explorer
    Script:10g中不用EM显示Active Session Count by Wait Class
    理解IMPDP ORA19505、ORA31640错误
    了解ocssd.bin如何控制RAC节点重启
    Oracle等待事件:NULL EVENT
    LGWR TRACE Warning: log write time
    MySql隔离级别多线程并发读取数据时的正确性
    Oracle事务处理—隔离级别
    Oracle函数详解
  • 原文地址:https://www.cnblogs.com/litou/p/2227864.html
Copyright © 2020-2023  润新知