ORACLE实现自定义序列号生成的方法
实际工作中,难免会遇到序列号生成问题,下面就是一个简单的序列号生成函数
(1)创建自定义序列号配置表如下:
--自定义序列 createtableS_AUTOCODE ( pk1VARCHAR2(32)primarykey, atypeVARCHAR2(20)notnull, ownerVARCHAR2(10)notnull, initcycleCHAR(1)notnull, cur_sernumVARCHAR2(50)notnull, zero_flgVARCHAR(2)notnull, sequencestyleVARCHAR2(50), memoVARCHAR2(60) ); --Addcommentstothecolumns commentoncolumnS_AUTOCODE.pk1is'主键'; commentoncolumnS_AUTOCODE.atypeis'序列号类型'; commentoncolumnS_AUTOCODE.owneris'序列号所有者'; commentoncolumnS_AUTOCODE.initcycleis'序列号递增'; commentoncolumnS_AUTOCODE.cur_sernumis'序列号'; commentoncolumnS_AUTOCODE.zero_flgis'序列号长度'; commentoncolumnS_AUTOCODE.sequencestyleis'序列号样式'; commentoncolumnS_AUTOCODE.memois'备注'; --Create/Recreateindexes createindexPK_S_AUTOCODEonS_AUTOCODE(ATYPE,OWNER);
(2)初始化配置表,例如:
insertintos_autocode(PK1,ATYPE,OWNER,INITCYCLE,CUR_SERNUM,ZERO_FLG,SEQUENCESTYLE,MEMO) values('0A772AEDFBED4FEEA46442003CE1C6A6','ZDBCONTCN','012805','1','200000','7','$YEAR$年$ORGAPP$质字第$SER$号','质押合同中文编号');
(3)自定义序列号生成函数:
创建函数:SF_SYS_GEN_AUTOCODE
CREATEORREPLACEFUNCTIONSF_SYS_GEN_AUTOCODE( I_ATYPEINVARCHAR2,/*序列类别*/ I_OWNERINVARCHAR2/*序列所有者*/ )RETURNVARCHAR2IS /**************************************************************************************************/ /*PROCEDURENAME:SF_SYS_GEN_AUTOCODE*/ /*DEVELOPEDBY:WANGXF*/ /*DESCRIPTION:主要用来生成自定义的序列号*/ /*DEVELOPEDDATE:2016-10-08*/ /*CHECKEDBY:*/ /*LOADMETHOD:F1-DELETEINSERT*/ /**************************************************************************************************/ O_AUTOCODEVARCHAR2(100);/*输出的序列号*/ V_INITCYCLES_AUTOCODE.INITCYCLE%TYPE;/*序列号递增*/ V_CUR_SERNUMS_AUTOCODE.CUR_SERNUM%TYPE;/*序列号*/ V_ZERO_FLAGS_AUTOCODE.ZERO_FLG%TYPE;/*序列号长度*/ V_SEQUENCESTYLES_AUTOCODE.SEQUENCESTYLE%TYPE;/*序列号样式*/ V_SEQ_NUMVARCHAR2(100);/*本次序列号*/ V_DATE_YEARCHAR(4);/*年份,如2016*/ V_DATE_YEAR_MONTHCHAR(6);/*年份月份,如201610*/ V_DATE_DATECHAR(8);/*年份月份日,如20161008*/ V_DATE_DATE_ALLCHAR(14);/*完整年份序列,如20161008155732*/ /* 支持的参数序列: $YEAR$-->年份 $YEAR_MONTH$-->年份+月份,不含汉子 $DATE$-->年份+月份+日期,不含汉子 $DATE_ALL$-->完整日期,不含汉子 $ORGAPP$-->所有者 $SER$-->当前序列号 */ --解决查询事务无法执行DML的问题 PragmaAutonomous_Transaction; BEGIN --查询复核条件的序列号配置 SELECTT.INITCYCLE, T.CUR_SERNUM, T.ZERO_FLG, T.SEQUENCESTYLE INTOV_INITCYCLE,V_CUR_SERNUM,V_ZERO_FLAG,V_SEQUENCESTYLE FROMS_AUTOCODETWHERET.ATYPE=I_ATYPEANDT.OWNER=I_OWNER; --格式化当前日期 SELECT TO_CHAR(SYSDATE,'yyyy'), TO_CHAR(SYSDATE,'yyyyMM'), TO_CHAR(SYSDATE,'yyyyMMdd'), TO_CHAR(SYSDATE,'yyyyMMddHH24MISS') INTOV_DATE_YEAR,V_DATE_YEAR_MONTH,V_DATE_DATE,V_DATE_DATE_ALL FROMDUAL; --日期处理 O_AUTOCODE:=REPLACE(V_SEQUENCESTYLE,'$YEAR$',V_DATE_YEAR); O_AUTOCODE:=REPLACE(O_AUTOCODE,'$YEAR_MONTH$',V_DATE_YEAR_MONTH); O_AUTOCODE:=REPLACE(O_AUTOCODE,'$DATE$',V_DATE_DATE); O_AUTOCODE:=REPLACE(O_AUTOCODE,'$DATE_ALL$',V_DATE_DATE_ALL); --所有者处理 O_AUTOCODE:=REPLACE(O_AUTOCODE,'$ORGAPP$',I_OWNER); --序号处理 V_SEQ_NUM:=TO_CHAR(TO_NUMBER(V_CUR_SERNUM)+TO_NUMBER(V_INITCYCLE)); --反写当前序列号,确保每次都是递增 UPDATES_AUTOCODETSETT.CUR_SERNUM=V_SEQ_NUMWHERET.ATYPE=I_ATYPEANDT.OWNER=I_OWNER; --不满足长度的前面补0 IFLENGTH(V_SEQ_NUM)<TO_NUMBER(V_ZERO_FLAG) THEN /* LOOP V_SEQ_NUM:='0'||V_SEQ_NUM; EXITWHENLENGTH(V_SEQ_NUM)=TO_NUMBER(V_ZERO_FLAG); ENDLOOP; */ V_SEQ_NUM:=LPAD(V_SEQ_NUM,TO_NUMBER(V_ZERO_FLAG),'0'); ENDIF; O_AUTOCODE:=REPLACE(O_AUTOCODE,'$SER$',V_SEQ_NUM); COMMIT; RETURNO_AUTOCODE; EXCEPTION --如果没有对应的配置项,则返回ERROR值 WHENNO_DATA_FOUNDTHEN ROLLBACK; DBMS_OUTPUT.put_line('thereisnoconfigasyouneed...'); RETURN'ERROR'; ENDSF_SYS_GEN_AUTOCODE;
(4)测试:
配置项:$YEAR$年$ORGAPP$质字第$SER$号
SELECTSF_SYS_GEN_AUTOCODE('ZDBCONTCN','012805')FROMDUAL;
(5)结果
2016年012805质字第0200001号
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。