zoukankan      html  css  js  c++  java
  • 【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,就可以为所有类似方式的年份流水号公用一个表,不必每种流水号都要建表盒函数;甚至还可以根据实际情况添加字段,把所有的复合流水号管理起来。到那个时候要注意一点,必须建好索引。

  • 相关阅读:
    初始化和实例化对象
    java设计模式
    构造方法的访问级别
    C#连接操作sqlite
    using三种用法
    C#获取当前日期时间
    C#生成excel到其他电脑生成报表时报错
    [Python] VSCode隐藏__pycache__文件夹
    [Git] 常用操作速查
    [Pytorch] 卷积尺寸计算
  • 原文地址:https://www.cnblogs.com/litou/p/2227864.html
Copyright © 2011-2022 走看看