oracle 顺序号生成函数。仿Sequence

时间:2023-02-13 12:16:32

问题提出自项目中的老代码:一个Bill表,存储所有的表单信息,比如:员工入职单,离职单等等。(别喷,我知道要分多个表。但领导的意愿你是没办法违背的)表单的单据号是以四个字母+年月日+数字顺序号来表示。每次取新单据号时要从Bill表里(按生成规则)查询出最大的那个单据号,再拆分出来,再给顺序号加1,组合好后再写回。哈哈这就是老代码。

随着软件行业的进步,各种技巧层出不穷。而针对顺序号生成的方法也有好巨大改进。

[Oracle]仿Oracle Sequence的自定义年份Sequence(适合任何数据库)

这里其中的一篇。看过这个之后就想自己动手也写一个。于是:

顺序号表

--id序列表
create table SEQUENCES
(
id VARCHAR2(20) not NULL PRIMARY KEY,--标识
minvalue NUMBER default 1,--最小值
maxvalue NUMBER default 9999999999999999999999999999,--最大值
currentvalue NUMBER DEFAULT 1,--当前值
increaseby NUMBER default 1,--增量
CYCLE CHAR(1) default '' --是否循环
)

生成函数

--获取 select NextValue('abc') from dual;
create or replace function NextValue(arg varchar2) return number IS
PRAGMA AUTONOMOUS_TRANSACTION;
Result number;
x NUMBER;
a NUMBER;
i NUMBER;
c Char(1);
BEGIN
IF TRIM(arg) IS NULL THEN--防止值入空字符串
RAISE_Application_Error(-6502,'param "arg" is not valide.',TRUE);
END IF;
<<top>>
SELECT COUNT(1) INTO x FROM Sequences WHERE ID = arg;
IF x = 0 THEN
BEGIN
BEGIN
INSERT INTO Sequences (ID) VALUES(arg);--防止并发同时插入相同的Id值。需要将id设为主键
EXCEPTION
WHEN OTHERS THEN
GOTO top;
END;
COMMIT;
RETURN 1;
END;
ELSE
BEGIN
SELECT s.currentvalue + s.increaseby,s.maxvalue,s.minvalue,s.cycle INTO Result,a,i,c FROM Sequences s WHERE ID = arg FOR update;--for update将锁定此行记录
IF RESULT < a THEN--未超出最大值
BEGIN
UPDATE Sequences SET currentvalue = Result WHERE ID = arg;
COMMIT;
return(Result);
END;
ELSE
BEGIN
IF c = '' THEN--不循环
BEGIN
RAISE_Application_Error(-6502,'out of range.',TRUE);
END;
ELSE
BEGIN--循环
UPDATE Sequences SET currentvalue = i WHERE ID = arg;
COMMIT;
RETURN i;
END;
END IF;
END;
END IF;
END;
END IF;
END;

是的,我使用了参数。这样就使得这个表更加有用,而非只单独处理一种类型顺序号。同时对并发进行了处理。让你只可能取得一个值,而不会出现重复的值。当然所有的result都没有进行格式化,而是直接输出。在PLSQL中进行函数test,打开两个窗口,单步调试,可以看到在insert或select for update时都会阻塞其它session对此表的操作。这样可以使用result的结果唯一。

oracle 顺序号生成函数。仿Sequence的更多相关文章

  1. &lbrack;原创&rsqb;oracle 顺序号生成函数。仿Sequence

    问题提出自项目中的老代码:一个Bill表,存储所有的表单信息,比如:员工入职单,离职单等等.(别喷,我知道要分多个表.但领导的意愿你是没办法违背的)表单的单据号是以四个字母+年月日+数字顺序号来表示. ...

  2. Oracle数据库中序列&lpar;SEQUENCE&rpar;的用法详解

    Oracle数据库中序列(SEQUENCE)的用法详解   在Oracle数据库中,序列的用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一个值.本文我们主要介绍了 ...

  3. Oracle中序列(Sequence)详解

    一 序列定义 序列(SEQUENCE)是序列号生成器,可以为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字).不占用磁盘空间,占用内存. 其主要用途是生成表的主键值,可以在插入语句中引用,也 ...

  4. Oracle笔记之序列&lpar;Sequence&rpar;

    Oracle中序列是一种数据对象,可以视为一个等差数列,我们自增就是一个遍历这个数列的过程,可以取当前值,也可以将当前值自加n后返回,Sequence与表没有太大的关系,有的时候如果表的主键是数值类型 ...

  5. oracle的序列号(sequence)

    oracle的自增列,要采用序列号(sequence). 初始化阶段要手动建立一个sequence,然后插入的时候,还要手动自己去读这个sequence的nextval赋给相关字段,如ID,麻烦的很. ...

  6. Oracle修改序列(Sequence)起始值问题

    Oracle 序列(Sequence)主要用于生成流水号,在应用中经常会用到,特别是作为ID值,拿来做表主键使用较多. 但是,有时需要修改序列初始值(START WITH)时,有同仁使用这个语句来修改 ...

  7. Oracle Auto Increment Column - Sequence as Default Value

        Solution 1: Prior to Oracle 11g, sequence assignment to a number variable could be done through ...

  8. Oracle中序列(SEQUENCE)的使用一例

    曾经在触发器中使用序列(SEQUENCE): create or replace trigger TRI_SUPPLIER before insert on SUPPLIER for each row ...

  9. oracle中利用trigger&comma;sequence自动生成ID

    http://zhanghong.iteye.com/blog/865937 1. 首先创建数据库表 SQL> create table customer( 2  id number(8) no ...

随机推荐

  1. 【转】零基础学习Fiddler抓包改包

    看到一篇讲关于Fiddler抓包工具的讲解,个人感觉写得很仔细,但是作者说禁止转载,那就放个链接Mark一下 http://tmq.qq.com/2016/12/fiddler_packet_capt ...

  2. c中动态使用数组

    #include <iostream> #include <fstream> #include<stdlib.h> #define MAXNUM 200 int I ...

  3. UVa12726 one Friend at a Time (位 广搜)

    题目链接:UVa12726 是个PDF,不好复制进来. 大意:有个人要追个妹子,想加妹子QQ,但是不知道谁规定的,玩QQ的人要加好友必须先要有至少k个共同好友.共有N个人玩QQ,编号为1到N,1是男主 ...

  4. liunx 内存文件 tmpfs

    tmpfs是Linux/Unix系统上的一种基于内存的文件系统.tmpfs可以使用您的内存或swap分区来存储文件 1 创建将被挂载的文件 mkdir /tmp/tmpfs/ 2 写入测试文件内容.大 ...

  5. JavaScript基础学习&lpar;八&rpar;&mdash&semi;事件

    一.鼠标移动事件      onmouseover: 鼠标移到了上面.      onmousemove: 鼠标移动了.      onmouseout: 鼠标移走了. window.onload = ...

  6. html超出显示省略号

    <span>装备自动回收,躺的赚钱,收入比上班还要高,古天乐都乐开了花装备自动回收,躺的赚钱,收入比上班还要高,古天乐都乐开了花装备自动回收,躺的赚钱,收入比上班还要高,古天乐都乐开了花& ...

  7. 一个简单的Quartz定时任务

    package com.shuadan.quartz; import org.springframework.scheduling.annotation.Scheduled; import org.s ...

  8. navicat 导入execl失败

    在使用navicat导入execl是遇到了如下图的错误 在更换多个版本的navicat后问题依然如故. 解决办法; 1.打开需要导入的execl 2.安装一个AccessDatabaseEngine_ ...

  9. vector 简介

    vector简介 vector是STL中最常见的容器,它是一种顺序容器,支持随机访问.vector是一块连续分配的内存,从数据安排的角度来讲,和数组极其相似, 不同的地方就是:数组是静态分配空间,一旦 ...

  10. hdu 5290 Bombing plan

    http://acm.hdu.edu.cn/showproblem.php?pid=5290 题意: 一棵树,每个点有一个权值wi,选择点i即可破坏所有距离点i<=wi的点,问破坏所有点 最少需 ...