56.使用编号表按日期生成刘少的案例

--编号表
CREATE TABLE tb_NO(
Name char(2) NOT NULL,                 --编号种类的名称
Days int NOT NULL,                     --保存的是该种编号那一天的当前编号
Head nvarchar(10) NOT NULL DEFAULT '', --编号的前缀
CurrentNo int NOT NULL DEFAULT 0,      --当前编号
BHLen int NOT NULL DEFAULT 6,          --编号数字部分长度
YearMoth int NOT NULL                  --上次生成编号的年月,格式YYYYMM
	DEFAULT CONVERT(CHAR(6),GETDATE(),112),
DESCRIPTION NVARCHAR(50),              --编号种类说明
TableName sysname NOT NULL,            --当前编号对应的原始表名
KeyFieldName sysname NOT NULL,         --当前编号对应的原始表编号字段名
PRIMARY KEY(Name,Days))

--这里以一种单据的7天的资料来做测试
INSERT tb_NO SELECT 'CG',1,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
UNION  ALL   SELECT 'CG',2,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
UNION  ALL   SELECT 'CG',3,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
UNION  ALL   SELECT 'CG',4,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
UNION  ALL   SELECT 'CG',5,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
UNION  ALL   SELECT 'CG',6,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
UNION  ALL   SELECT 'CG',7,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
GO

--获取新编号的存储过程
CREATE PROC p_NextBH
@Name char(2),            --编号种类
@Date datetime=NULL,     --要获取的当前日期,不指定则为系统当前日期
@BH nvarchar(20) OUTPUT --新编号
AS
IF @Date IS NULL SET @Date=GETDATE()
BEGIN TRAN
	--从编号表中获取新编号
	UPDATE tb_NO SET 
		@BH=Head
			+CONVERT(CHAR(6),@Date,12)
			+RIGHT(POWER(10,BHLen)
				+CASE 
					WHEN YearMoth=CONVERT(char(6),@Date,112)
					THEN CurrentNo+1
					ELSE 1 END
			,BHLen),
		CurrentNo=CASE 
			WHEN YearMoth=CONVERT(char(6),@Date,112)
			THEN CurrentNo+1
			ELSE 1 END,
		YearMoth=CONVERT(char(6),@Date,112)
	WHERE Name=@Name 
		AND Days=DAY(@Date)
		AND YearMoth<=CONVERT(char(6),@Date,112)

	--如果要获取的编号在编号表中已经过期,则直接从原始表中取编号
	IF @@ROWCOUNT=0
	BEGIN
		DECLARE @s nvarchar(4000)
		SELECT @s=N'SELECT @BH='
			+QUOTENAME(Head+CONVERT(CHAR(6),@Date,12),N'''')
			+N'+RIGHT('+CAST(POWER(10,BHLen)+1 as varchar)
			+N'+ISNULL(RIGHT(MAX('+QUOTENAME(KeyFieldName)
			+N'),'+CAST(BHLen as varchar)
			+N'),0),'+CAST(BHLen as varchar)
			+N') FROM '+QUOTENAME(TableName)
			+N' WITH(XLOCK,PAGLOCK) WHERE '
			+QUOTENAME(KeyFieldName)
			+N' like '+QUOTENAME(Head+CONVERT(CHAR(6),@Date,12)+N'%',N'''')
		FROM tb_NO
		WHERE Name=@Name 
			AND Days=DAY(@Date)
			AND YearMoth>CONVERT(char(6),@Date,112)
		IF @@ROWCOUNT>0
			EXEC sp_executesql @s,N'@BH nvarchar(20) OUTPUT',@BH OUTPUT
	END
COMMIT TRAN
GO

CREATE TABLE tb(BH char(12))
--获取 CG 的新编号
DECLARE @bh char(12)
EXEC p_NextBH 'CG','2005-1-1',@bh OUT
SELECT @bh
--结果: CG0501010001

EXEC p_NextBH 'CG','2005-1-1',@bh OUT
SELECT @bh
--结果: CG0501010002

EXEC p_NextBH 'CG','2005-1-2',@bh OUT
SELECT @bh
--结果: CG0501020001

EXEC p_NextBH 'CG','2005-2-2',@bh OUT
SELECT @bh
--结果: CG0402020001

EXEC p_NextBH 'CG','2004-2-2',@bh OUT
SELECT @bh
--结果: CG0402020001
GO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值