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