ORACLE实现自定义序列号生成

实际工作中,难免会遇到序列号生成问题,下面就是一个简单的序列号生成函数

(1)创建自定义序列号配置表如下:

--自定义序列
create table S_AUTOCODE
(
  pk1           VARCHAR2(32) primary key,
  atype         VARCHAR2(20) not null,
  owner         VARCHAR2(10) not null,
  initcycle     CHAR(1) not null,
  cur_sernum    VARCHAR2(50) not null,
  zero_flg      VARCHAR(2) not null,
  sequencestyle VARCHAR2(50),
  memo          VARCHAR2(60)
);
-- Add comments to the columns
comment on column S_AUTOCODE.pk1  is ‘主键‘;
comment on column S_AUTOCODE.atype  is ‘序列号类型‘;
comment on column S_AUTOCODE.owner  is ‘序列号所有者‘;
comment on column S_AUTOCODE.initcycle  is ‘序列号递增‘;
comment on column S_AUTOCODE.cur_sernum  is ‘序列号‘;
comment on column S_AUTOCODE.zero_flg  is ‘序列号长度‘;
comment on column S_AUTOCODE.sequencestyle  is ‘序列号样式‘;
comment on column S_AUTOCODE.memo  is ‘备注‘;
-- Create/Recreate indexes
create index PK_S_AUTOCODE on S_AUTOCODE (ATYPE, OWNER);

(2)初始化配置表,例如:

insert into s_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
CREATE OR REPLACE FUNCTION SF_SYS_GEN_AUTOCODE(
          I_ATYPE IN VARCHAR2,  /*序列类别*/
          I_OWNER IN VARCHAR2   /*序列所有者*/
) RETURN VARCHAR2 IS
        /**************************************************************************************************/
        /* PROCEDURE NAME : SF_SYS_GEN_AUTOCODE                                                           */
        /* DEVELOPED BY   : WANGXF                                                                        */
        /* DESCRIPTION    : 主要用来生成自定义的序列号                                                    */
        /* DEVELOPED DATE : 2016-10-08                                                                    */
        /* CHECKED BY     :                                                                               */
        /* LOAD METHOD    : F1-DELETE INSERT                                                              */
        /**************************************************************************************************/

       O_AUTOCODE VARCHAR2(100);                        /*输出的序列号*/
       V_INITCYCLE S_AUTOCODE.INITCYCLE%TYPE;       /*序列号递增*/
       V_CUR_SERNUM S_AUTOCODE.CUR_SERNUM%TYPE;     /*序列号*/
       V_ZERO_FLAG S_AUTOCODE.ZERO_FLG%TYPE;        /*序列号长度*/
       V_SEQUENCESTYLE S_AUTOCODE.SEQUENCESTYLE%TYPE;/*序列号样式*/
       V_SEQ_NUM VARCHAR2(100);                     /*本次序列号*/
       V_DATE_YEAR CHAR(4);                         /*年份,如2016*/
       V_DATE_YEAR_MONTH CHAR(6);                   /*年份月份,如201610*/
       V_DATE_DATE CHAR(8);                         /*年份月份日,如20161008*/
       V_DATE_DATE_ALL CHAR(14);                    /*完整年份序列,如20161008155732*/

       /*
          支持的参数序列:
          $YEAR$ --> 年份
          $YEAR_MONTH$ --> 年份+月份,不含汉子
          $DATE$ --> 年份+月份+日期,不含汉子
          $DATE_ALL$ --> 完整日期,不含汉子
          $ORGAPP$ --> 所有者
          $SER$ --> 当前序列号
       */

       --解决查询事务无法执行DML的问题
       Pragma Autonomous_Transaction;
BEGIN
       -- 查询复核条件的序列号配置
       SELECT T.INITCYCLE,
              T.CUR_SERNUM,
              T.ZERO_FLG,
              T.SEQUENCESTYLE
              INTO V_INITCYCLE,V_CUR_SERNUM,V_ZERO_FLAG,V_SEQUENCESTYLE
       FROM S_AUTOCODE T WHERE T.ATYPE=I_ATYPE AND T.OWNER=I_OWNER ;

       --格式化当前日期
       SELECT
            TO_CHAR(SYSDATE,‘yyyy‘),
            TO_CHAR(SYSDATE,‘yyyyMM‘),
            TO_CHAR(SYSDATE,‘yyyyMMdd‘),
            TO_CHAR(SYSDATE,‘yyyyMMddHH24MISS‘)
            INTO  V_DATE_YEAR,V_DATE_YEAR_MONTH,V_DATE_DATE,V_DATE_DATE_ALL
       FROM DUAL;

       -- 日期处理
       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));

       --反写当前序列号,确保每次都是递增
       UPDATE S_AUTOCODE T SET T.CUR_SERNUM=V_SEQ_NUM WHERE T.ATYPE=I_ATYPE AND T.OWNER=I_OWNER ;

       --不满足长度的前面补0
       IF LENGTH(V_SEQ_NUM) < TO_NUMBER(V_ZERO_FLAG)
         THEN
           LOOP
             V_SEQ_NUM := ‘0‘||V_SEQ_NUM;
           EXIT WHEN LENGTH(V_SEQ_NUM) = TO_NUMBER(V_ZERO_FLAG);
           END LOOP;
       END IF;

       O_AUTOCODE := REPLACE(O_AUTOCODE,‘$SER$‘,V_SEQ_NUM);

       COMMIT;
       RETURN O_AUTOCODE;
EXCEPTION
       --如果没有对应的配置项,则返回ERROR值
       WHEN NO_DATA_FOUND THEN
         ROLLBACK;
         DBMS_OUTPUT.put_line(‘there is no config as you need...‘);
         RETURN ‘ERROR‘;
END SF_SYS_GEN_AUTOCODE;

(4)测试:

配置项:$YEAR$年$ORGAPP$质字第$SER$号
SELECT SF_SYS_GEN_AUTOCODE(‘ZDBCONTCN‘,‘012805‘) FROM DUAL;

(5) 结果

2016年012805质字第0200001号
时间: 2024-11-19 19:44:58

ORACLE实现自定义序列号生成的相关文章

zookeeper+redies 系统序列号生成

系统序列号生成服务是写的一个jar包,不依赖其他服务和数据,以下提供部分代码作为一个思路,作为大量数据订单生成时,不再使用数据库表的自增设置,由个系统模块自行生成. 一.使用规则 组成结构 + 生成时间 yyMMddHHmmss + 3位服务节点(001 到 999) + N位滚动序列(000001 到 999999 长度可自定义) 重复性解决方案 + 每秒钟单节点产生序列大于 999999 将会造成序列重复 + 每秒钟单节点产生序列小于 999999 则不会重复. 分布式解决方案 + 应用启动

唯一序列号生成,自測支持高并发,不支持集群

序列号组成:前缀 + 日期 + 尾数 比如:ZC20140806000001 总共两个组成:一个枚举类.一个静态生成器.另外须要设计自己主动任务每日凌晨或其它时间重置一次尾数. 先上枚举类: package com.boxmeal.base.constant.common; import java.util.concurrent.atomic.AtomicInteger; /** * 序列号生成枚举 * @author bling * */ public enum SNEnum { // 订单编

Oracle存储过程-自定义数据类型,集合,遍历取值

摘要 Oracle存储过程,自定义数据类型,集合,遍历取值 目录[-] 0.前言 1.Packages 2.Packages bodies 3.输出结果 0.前言 在Oracle的存储过程中,可能会遇到数据处理,假如我们目前的功能在一个Packages中 Packages封装了多个不同功能的Procedure,我们在一个Procedure里面进行统计 在另外一个Procedure进行计算 这就需要一个存放结果集的地方 以前的解决方案是:建立了一个临时表,数据统计出来后,放入临时表中 在另外一个P

Mybatis框架(9)---Mybatis自定义插件生成雪花ID做为表主键项目

Mybatis自定义插件生成雪花ID做为主键项目 先附上项目项目GitHub地址 spring-boot-mybatis-interceptor 有关Mybatis雪花ID主键插件前面写了两篇博客作为该项目落地的铺垫. 1.Mybatis框架---Mybatis插件原理 2.java算法---静态内部类实现雪花算法 该插件项目可以直接运用于实际开发中,作为分布式数据库表主键ID使用. 一.项目概述 1.项目背景 在生成表主键ID时,我们可以考虑主键自增 或者 UUID,但它们都有很明显的缺点 主

Ember.js 入门指南——自定义序列号器

在Ember应用中,序列化器会格式化与后台交互的数据,包括发送和接收的数据.默认情况下会使用JSON API序列化数据.如果你的后端使用不同的格式,Ember Data允许你自定义序列化器或者定义一个完全不同的序列化器. Ember Data内置了三个序列化器.JSONAPISerializer是默认的序列化器,用与处理后端的JSON API.JSONSerializer是一个简单的序列化器,用与处理单个JSON对象或者是处理记录数组.RESTSerializer是一个复杂的序列化器,支持侧面加

【python】13位随机序列号生成工具 源码分析

By Dolphin,BeiJing,20150712 0X00  背景 最近在学习python 这门语言,刚学完for循环,对于很多语句语法都不太熟悉.就在今天,看到有某个网站的活动,需要输入一个13位的序列号来判断你是否中奖,但是这个13位序列号是需要购买他们家的产品才能获得,得耗费一定的金钱,于是我就在想,是不是能自己写一个序列号生成器来碰碰运气,所以决定运用刚学的python的初级知识进行编写. 0X01  知识点准备 这个工具主要的功能是生成随机字母做序列号,python中的rando

WF4.0以上使用代码完整自定义动态生成执行工作流Xaml文件

给大家分享一下,如何完全使用代码自定义的创建生成工作流文件(用代码创建Xaml文件),并且动态加载运行所生成的工作流. 工作流生成后 在Xaml文件里的主要节点如下: 输入输出参数 <x:Members> <x:Property Name="Item" Type="InArgument(qm:RuleModel)" /> <x:Property Name="Result" Type="OutArgument

Hibernate遇到oracle之主键生成策略

一直用Hibernate+mysql,感觉Hibernate很好用,也出过什么大问题:这周,公司的产品要部署到Orecle,虽然产品号称支持Oracle但是我自己知道,这个产品压根儿就没在Oracle上测试过,更不要是使用了.于是就开始紧罗密布的测试了,问题自然一大堆,现在说一个关于主键生成策略的问题. 首先,众所周知,Hibernate可以自动建表.当我们把项目部署好,运行的时候发现,确实自动建表了,但是少了很多表,就是有的表生成了,有的表木有生成,这就让人很头疼了.一波操作之后,发现Hibe

友盟自定义分享-生成带图片的二维码,自定义分享布局

public class UmengShare { private Activity activity = null; private UMSocialService mController = null; private Dialog shareDialog = null; private Bitmap bitmapCode = null; public UmengShare(Activity activity){ this.activity = activity; } public void