今天抽了点时间,写了一个通用的生成编号的程序!

我的生成规则为年月日+两位编号,即:yyyyMMdd+两位编号,譬如:2018101001 / 2018101002 / 2018101003

首先,一个项目中有很多表需要生成编号,譬如:产品编号,评估编号,学生学号等

下面看看我的思路,如下:

首先创建一张表,如下:

create table CM_CodeNo
(
Id int identity(1,1) primary key not null,
CodeCate varchar(50) not null unique,--现场考察 非设计类履约评估等
VersionNum TimeStamp not null,
CodeYear int,
CodeMonth int,
CodeDay int,
CodeValue varchar(20),
CodeCount int,
AddTime datetime default(getdate()),
)

简单解读下这张表的构造:

CodeCate:编号分类,譬如:产品编号、评估编号等

VersionNum:乐观锁版本号,用于处理并发,有兴趣的可参考鄙人的博客:https://www.cnblogs.com/chenwolong/p/BF.html#4094056

CodeYear:年

CodeMonth:月

CodeDay:日

CodeCount:代表今天生产了几个编号

AddTime:生产时间

CodeValue:无效字段,没用到...

表的解读就这么多,现在来看一组存储过程:

ALTER proc [dbo].[LockCodeNoProc] --
(
@CodeCate nvarchar(50),
@IsSuccess bit=0 output
)
as
declare @currentYear as int
declare @currentMonth as int
declare @currentDay as int
declare @count as int
declare @CodeCount as int
declare @flag as TimeStamp
declare @rowcount As int set @currentYear=DateName(year,GetDate())
set @currentMonth=DateName(month,GetDate())
set @currentDay=DateName(day,GetDate())
begin tran
select @count=count(1) from CM_Code where CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate
if @count=0
begin
insert into CM_Code(CodeCate,CodeYear,CodeMonth,CodeDay,CodeValue,CodeCount,AddTime)
values(@CodeCate,@currentYear,@currentMonth,@currentDay,'',1,GETDATE())
select CodeCount from CM_Code where CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate
end
else
begin
select @count=CodeCount,@flag=VersionNum from CM_Code where CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate
--waitfor delay '00:00:10' --可用于模拟并发
update CM_Code set CodeCount=@count+1 where VersionNum=@flag and CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate
set @rowcount=@@ROWCOUNT
select CodeCount from CM_Code where CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate if @rowcount>0
begin
set @IsSuccess=1
select @IsSuccess
end
else
begin
set @IsSuccess=0
select @IsSuccess
end
end
commit tran

调用这个存储过程,会返回当前分类今天生产的编号数量,

时间有限,不作过多解读,大家自行理解,

下面是C#代码:

    public class GetCode
{
public static string GetCodeNo(Enum CodeCate)
{
PortalCodeModel M = new PortalCodeModel();
M = U_GetCode.GetCodeNo(CodeCate);
//--模拟发生了并发,需要等待,重复请求,最大请求次数为10次
int retry = ;
while (!M.IsSuccess && retry > )
{
retry--;
GetCodeNo(CodeCate);
}
//
string code = GetCodeString(M.Result);
return code; } public static string GetCodeString(int CodeCount)
{
string initStr = DateTime.Now.ToString("yyyyMMdd");
int initLen = initStr.Length;
int Len = CodeCount.ToString().Length;
int MaxLen = ;
string ling = string.Empty;
int TotalLen = initLen + Len;
if (TotalLen <= MaxLen)
{
switch (Len)
{
case :ling = initStr + "" + CodeCount.ToString();break;
default: ling = initStr + CodeCount.ToString(); break;
}
}
return ling;
}
}

DAL层如下:

        public static PortalCodeModel GetCodeNo(Enum CodeCate)
{
using (DataAccessBroker broker = DataAccessFactory.Instance())
{
PortalCodeModel M = new PortalCodeModel();
DataAccessParameterCollection parameters = new DataAccessParameterCollection();
parameters.AddWithValue("@CodeCate", CodeCate.ToString());
parameters.AddWithValue("@IsSuccess", ParameterDirection.ReturnValue); DataSet ds = broker.FillCommandDataSet("LockCodeNoProc", parameters);
//
if (ds != null && ds.Tables.Count > )
{
var Result = Convert.ToInt32(ds.Tables[].Rows[]["CodeCount"]);
var Bol = (ds.Tables[].Rows[][]).ToString();
if (Bol == "True")
{
M.Result = Result;
M.IsSuccess = true;
}
else
{
M.Result = Result;
M.IsSuccess = false;
}
}
return M;
}
}

枚举层如下:

    /// <summary>
/// 各个枚举的‘值’使用表名即可
/// </summary>
public enum CodeCateEnum
{
[Description("现场考察")]
Inspection,
[Description("非设计类过程评估")]
EvluationPros,
[Description("非设计类履约评估")]
EvluationPlan,
}

OK ,就这么多,太忙,就不做过多的演示了!

  public class PortalCodeModel
{
public bool IsSuccess { get; set; }
public int Result { get; set; }
}

说明下:当返回 IsSuccess 为 False 时,及说明发生了并发,应执行重复请求。这里采用的方式是:重复请求十次,直至成功为止!

C# 代码执行的时候,当第一次执行存储过程,会异常,请自行处理!

谢谢!

C# 生成编号(防并发)的更多相关文章

  1. EndNote在Word中插入文献不能自动生成编号 - 解决方案

    本文出处:新浪博客“小数码植物摄影”之http://blog.sina.com.cn/s/blog_629be3eb0100sih3.html 新浪博客“小数码植物摄影”首页:http://blog. ...

  2. sql语句单据编号生成防并发

    有用户反馈说发现重复单据号,检查发现以下单据号被分配给了不同的两个职工 系统中使用语句exec GetNewOrderNumber 'pwgnumber','PWG',1, @pwg_number o ...

  3. 【SQL-自动生成编号】按规则自动生成单据编号 以及并发问题_使用触发器、函数 等

    描述:每种单据新建时,自动生成它的单据编号. 规则如:固定码+日期+流水号 (ABC1603180001) 方法一:触发器 触发器的缺点是,执行了sql之后才看到编码. 测试:流水号不能超过最大数,否 ...

  4. C#生成编号

    //自动生成账单编号 public string GetNewPoID(string Prefix) { string NewPoID = Prefix + DateTime.Now.Year.ToS ...

  5. redis 初步认识四(redis锁,防并发)

    using System; namespace ConsoleAppRedis { class Program { static void Main(string[] args) { //第一种,无登 ...

  6. SQL SERVER 批量生成编号

    开始: 在testing中,为了模拟orders,有个要求给数据库dba,如何通过后台数据库脚本快速批量生成orders. 分析 站在数据库角度,批量生成orders,也就是批量生成表中的行数据. s ...

  7. 支付宝防并发方案之"一锁二判三更新"

    每年支付宝在双11和双12的活动中,都展示了绝佳的技术能力.这个能力不但体现在处理高TPS量的访问,更体现在几乎不会出错,不会出现重复支付的情况,那这个是怎么做到的呢? 诚然,为了实现在高并发下仍不会 ...

  8. 自动生成编号(B开头后跟6位,数据库查询不重复)

    private string GetAccountNo() { try { string shortName="B"; "; //查询数据库 7位且包含“B” & ...

  9. odoo之自动生成编号问题

    单独的seq.xml文件 <?xml version="1.0" encoding="utf-8"?><openerp> <dat ...

随机推荐

  1. hdu-2027题&&gets/getchar的区别

    hdu-2027题(水题~~~) 统计每个元音字母在字符串中出现的次数. Input输入数据首先包括一个整数n,表示测试实例的个数,然后是n行长度不超过100的字符串. Output对于每个测试实例输 ...

  2. 章节七、3-ArrayList和LinkedList对比

    一.创建集合并添加元素(从末尾位置添加) package ZangJie7; import java.util.ArrayList; import java.util.LinkedList; impo ...

  3. 《React与Redux开发实例精解》读书笔记

    第五章 JSX语法 class属性改为className for属性改为htmlFor jsx中javascript表达式必须要有返回值,使用三元操作符 所有的标签必须闭合 input img等 re ...

  4. .NET Core 2.0

    下载 Visual Studio 2017 version 15.3 下载 .NET Core 2.0 下载 Visual Studio for Mac 微软今天发布了.NET Core 2.0 版本 ...

  5. Scala抽象类型

    package big.data.analyse.scala import scala.io.{BufferedSource, Source} /** * 抽象类型 * Created by zhen ...

  6. The operation could not be performed because the OLE DB provider 'SQLOLEDB' was unable to begin a distributed transaction

    今天遇到一起关于分布式事务错误的案例,如下所示,执行SQL脚本时报错, 错误信息具体如下所示: [OLE/DB provider returned message: 新事务不能登记到指定的事务处理器中 ...

  7. PL/SQL重新编译包无反应案例2

    在这篇"PL/SQL重新编译包无反应"里面介绍了编译包无反应的情况,今天又遇到一起案例, 在测试环境中,一个包的STATUS为INVALID,重新编译时,一直处于编译状态,检查发现 ...

  8. 排序算法----冒泡排序java(写得绝对比其他博文易懂明了实用)

    本来不想写的,看到别人写的都不符合自己心意 需进行n(n-1)/2次比较和记录移动,时间复杂度为O(n*n) import java.util.Arrays; import java.util.Sca ...

  9. [20181108]12c sqlplus rowfetch参数4.txt

    [20181108]12c sqlplus rowfetch参数4.txt --//12cR2 可以改变缺省rowfetch参数.11g之前缺省是1.通过一些测试说明问题.--//前几天做的测试有点乱 ...

  10. [20180926]共享池中的NETWORK BUFFER.txt

    [20180926]共享池中的NETWORK BUFFER.txt --//最近几天一直在探究SQL*Net more data from client 相关等待事件,发现SDU相关,自己也网上探究一 ...