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号
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。