热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

单据号生成

熟悉仓库管理系统的人会比较清楚,系统中统有各种各样的单据,如补货单、进货单、出库单等等。在这里,我们先介绍一种单据编码定义规则࿱

熟悉仓库管理系统的人会比较清楚,系统中统有各种各样的单据,如补货单 、进货单、出库单等等。在这里,我们先介绍一种单据编码定义规则:

 

[仓库编码][单据类型][YYMMDD][4位流水号]

 

如:0101JH1202030001:

仓库编码:0101

单据类型:JH(进货)

生成日期:120203(120203)

四位流水:0001

 

上述规则是一种比较简单的编码方式,要注意的是上述的流水号在仓库、单据和日期之间不共享,即是说不同的仓库、不同的单据每天的流水号都是从1开始。

 

首先,我们采用一个表NoType,用来记录系统中的各种单据类型。

 

序号

列名

数据类型

长度

主键

允许空

默认值

说明

1

NoType

varchar

10

 

单据类型

2

NoTypeName

nvarchar

50

 

 

单据名称

 

然后,我们使用另一个表NoGenerate来记录每个仓库每种单据当日的最后生成的流水号。

 

序号

列名

数据类型

长度

主键

允许空

默认值

说明

1

Date

nchar

10

 

日期

2

NoType

varchar

10

 

类型

3

HouseCode

varchar

20

 

库房编号

4

LatestNo

int

4

((1))

最后流水号

 

使用Update更新方式

CREATE PROCEDURE [dbo].[ProcNoGenerateGet2]
      @NoType VARCHAR(10),
      @HouseCode VARCHAR(20),
      @length INT,
      @code VARCHAR(200) OUTPUT
AS
 
--判断号码类型是否合法 
IF NOT EXISTS ( SELECT  0
                FROM    NoType(NOLOCK)
                WHERE   NoType = @NoType )
BEGIN   
     SET @code='0'   
     RETURN   
END   
   
DECLARE @LatestNo INT   
DECLARE @date NCHAR(10)   
SET @date=CONVERT(NCHAR(10),GETDATE(),120)   
   
UPDATE  NoGenerate
SET     @LatestNo=LatestNo=LatestNo+1
WHERE   Date = @date
        AND NoType = @NoType
        AND HouseCode = @HouseCode   
IF (@@rowcount = 0)
BEGIN    
     INSERT INTO NoGenerate (Date,NoType,HouseCode)
     VALUES (@Date,@NoType,@HouseCode)    
     SET @latestNo=1   
END   
   
SET @code=dbo.NumberAddZeroPre(@LatestNo,@length)   
SET @code=@HouseCode+@NoType+SUBSTRING(REPLACE(@date,'-',''),3,6)+@code

 

其中,函数NumberAddZeroPre用来生成指定长度的流水号。

 

CREATE FUNCTION [dbo].[NumberAddZeroPre] (@num INT,@len INT)
RETURNS VARCHAR(20)
AS
BEGIN
    DECLARE @str VARCHAR(20)
    SET @str=CAST(@num AS VARCHAR)
    DECLARE @curLen INT
    SET @curLen=LEN(@str)
    WHILE (&#64;curLen < &#64;len)
          BEGIN
                SET &#64;str&#61;&#39;0&#39;&#43;&#64;str
                SET &#64;curLen&#61;&#64;curLen&#43;1
          END
    RETURN &#64;str
END

 

使用Update方式进行单据号获取&#xff0c;足以满足大部情况的需求&#xff0c;但是在数据量和并发量大到一定程序的时候&#xff0c;会产生大量的数据锁&#xff0c;严重影响到系统性能&#xff0c;这时候&#xff0c;我们可以另一种解决方案&#xff0c;使用Insert方式实现流水号获取。

使用Insert插入方式

新建一表&#xff0c;定义主键时加上with(ignore_dup_key&#61;on)&#xff0c;忽略重复的记录。

 

1 CREATE TABLE NoGenerate
2 (
3     Date NCHAR(10NOT NULL,
4     NoType VARCHAR(10NOT NULL,
5     HouseCode VARCHAR(20NOT NULL,
6     LatestNo INT NOT NULL DEFAULT 1,
7         CONSTRAINT PK_NOGENERATE PRIMARY KEY (Date,NoType,HouseCode,LatestNo)
8 )
9 Go

 

新建一存储过程&#xff0c;采用插入的方式得到递增的流水号。

 

CREATE PROCEDURE [dbo].[ProcNoGenerateGet3]
    &#64;NoType varchar(10),
    &#64;HouseCode varchar(20),
    &#64;length int,
    &#64;code varchar(200) output
AS
 
--判断号码类型是否合法
if not exists(select 0 from NoType(nolock) where NoType&#61;&#64;NoType)
begin
    set &#64;code&#61;&#39;0&#39;
    return
end
 
--当前日期、最大流水号、是否采号成功&#xff08;&#xff1a;成功&#xff0c;&#xff1a;未成功&#xff09;
declare &#64;date int &#61; cast(Convert(nchar(8),GetDate(),112as int)
declare &#64;dateS nchar(10&#61; Convert(nchar(10),GetDate(),120)
declare &#64;LatestNo int
declare &#64;LatestNoOld int
declare &#64;LatestDateForDel int &#61; 0
declare &#64;LatestNoForDel int  &#61; 0
 
--删除前一天的数据
if ((select count(1from NoGenerateEx(nolock) where NoType &#61; &#64;NoType and HouseCode &#61; &#64;HouseCode)> 1500)
begin
    select &#64;LatestDateForDel &#61; T2.intDate, &#64;LatestNoForDel &#61; T2.LatestNo from (
        select top 1 T1.* from (
            select top 1500 nge.intDate,nge.LatestNo from NoGenerateEx nge(nolock)
            where NoType &#61; &#64;NoType and HouseCode &#61; &#64;HouseCode
            order by nge.intDate,nge.LatestNo
        ) T1 order by t1.intDate desc, T1.LatestNo desc
    ) T2
    delete from NoGenerateEx with(rowlock,xlock) where [intDate] < &#64;LatestDateForDel AND NoType &#61; &#64;NoType and HouseCode &#61; &#64;HouseCode
    delete from NoGenerateEx with(rowlock,xlock) where [intDate] &#61; &#64;LatestDateForDel and LatestNo < &#64;LatestNoForDel AND NoType &#61; &#64;NoType and HouseCode &#61; &#64;HouseCode
end
 
declare &#64;insertRe smallint &#61; 0
while(&#64;insertRe &#61; 0)
BEGIN
   
    set &#64;LatestNo &#61; isnull((select max(LatestNo) from NoGenerateEx(nolock)
            where [intDate] &#61; &#64;date and NoType &#61; &#64;NoType and HouseCode &#61; &#64;HouseCode),0&#43; 1
 
    --插入新号
    insert into NoGenerateEx([intDate],NoType,HouseCode,LatestNo)values(&#64;date,&#64;NoType,&#64;HouseCode,&#64;LatestNo
    set &#64;insertRe&#61;&#64;&#64;ROWCOUNT
end
 
--返回值
set &#64;code &#61; &#64;HouseCode&#43;&#64;NoType&#43;right(CAST(&#64;date as varchar(8)),6)&#43;dbo.NumberAddZeroPre(&#64;LatestNo,&#64;length)

 

采用此方式生成单据编码&#xff0c;与Update方式相比&#xff0c;会产生大量的数据&#xff0c;所以在存储过程中&#xff0c;需要不断的进行数据的清除&#xff0c;以保证性能&#xff0c;但是在并发比较高的情况下&#xff0c;优点也很明显&#xff0c;由于采用了Insert操作&#xff0c;所以不会出现锁表的现象。

 

 指定长度流水号生成参考&#xff1a;http://www.cnblogs.com/wych/archive/2009/08/06/1540302.html 

转:https://www.cnblogs.com/wych/archive/2012/02/03/2337390.html



推荐阅读
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
author-avatar
mobiledu2502858037
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有