MSSQL通过函数生成唯一编号的方法?

0
应用场景:在业务系统中,经常需要根据一定的规则生成增长的编号来作为项目编号,单据编号等。

比如某种业务单号的规则如下:
XB-20130708001 单据编号
XB 为业务简称
20130708是日期
001为当天自动增长数值,表示当天生成了多少单据

请使用MSSQL函数来实现此功能需求。

也可以说清思路即可。
已邀请:
3

Gabriel - 茕茕白兔 东走西顾 衣不如新 人不如故 2013-07-08 回答

新手村码农示例,请老师拍砖
根据业务需要可能有2种情况,业务日期与单据流水创建,当前日期与单据流水号创建.
1.获取流水号规则类型组合,增加种子流水号表.如业务类型名称 单据业务日期 流水号;
2.获取流水号规则类型组合,增加种子流水号表.如业务类型名称 当前系统日期 流水号;
其实基本原理一样,现在写一个简单的例子,获取当前日期来插入
表设计
1.业务表:正常业务存储的表,包含编号等等数据信息
2.日期种子表:当用户选择为日期 流水号的方式时,需要增加一个种子表来记录流水号,目的是为了确保业务表中编号的唯一性.
下面将设计成2个简单的表
1.业务表AC
编号:XLH,VARCHAR(200);
    []日期种子表AD:[/]
日期:RQ,VARCHAR(100);
种子编号:NO,INT;
现在表创建成功后,需要一个获取当前的函数,我先写一个视图,用来查询当前日期,格式为YYYYMMDD
CREATE VIEW V_RQ
AS
SELECT RQ=CONVERT(VARCHAR(10),GETDATE(),112)
GO
那么通过查询该视图就既可以获得当前日期情况.
回来我们的主题,如何生成唯一的编号
思路:在种子表中插入当前日期,并且插入初始流水号,当然如果存在则不插入,在每次新增业务单据编号前获取当前种子编号+1,然后插入业务表,然后更改种子表序号,下面代码示例:

DECLARE @LX VARCHAR(10) --声明编号开头类型
DECLARE @FH VARCHAR(10) --声明编号中间符号
DECLARE @RQ VARCHAR(10) --声明编号中间日期
DECLARE @zz VARCHAR(10) --声明编号中流水号

SELECT @LX='XB' --定义编号开头类型为:XB
SELECT @FH='-' --定义编号中间符号为:-
SELECT @RQ=DT FROM V_RQ --定义编号中间日期为:系统当前日期

--判断日期的种子表是否有当前日期,如果没有插入一条当前日期,并种子标示为1,如有有将其查询出结果不做操作.
IF ((SELECT COUNT(1) FROM AD WHERE RQ=@RQ)=0)
INSERT INTO AD(RQ,NO) VALUES(@RQ,0)
ELSE
SELECT RQ,NO FROM AD
--获取当前日期流水编号+1
SELECT @zz=(SELECT NO FROM AD WHERE RQ=@RQ)+1
--插入业务编号
INSERT INTO AC(XLH) VALUES(@LX+@FH+@RQ+@FH+@zz)
--插入结束后更改种子表
UPDATE AD SET NO=NO+1 WHERE RQ=@DT

当然代码还有许多改进,希望老师指点批评.
1

Gabriel - 茕茕白兔 东走西顾 衣不如新 人不如故 2013-07-08 回答

第二种写法:
DECLARE @LX VARCHAR(10) --声明编号开头类型
DECLARE @FH VARCHAR(10) --声明编号中间符号
DECLARE @RQ VARCHAR(10) --声明编号中间日期
DECLARE @NO INT --声明编号中流水号

SELECT @LX='XB' --定义编号开头类型为:XB
SELECT @FH='-' --定义编号中间符号为:-
SELECT @DT=DT FROM V_RQ --定义编号中间日期为:系统当前日期

--判断日期的种子表是否有当前日期,如果没有插入一条当前日期,并种子标示为1,如有有将其查询出结果不做操作.
IF ((SELECT COUNT(1) FROM AD WHERE RQ=@RQ)=0)
INSERT INTO AD(RQ,NO) VALUES(@RQ,1)--默认将插入的流水号为1
ELSE
SELECT RQ,NO FROM AD
--获取编号的同时修改种子表
UPDATE AD SET @NO = NO,NO = NO+1 WHERE RQ =@RQ

--插入业务编号
INSERT INTO AC(XLH) VALUES(@LX+@FH+@DT+@FH+(CONVERT(VARCHAR(100),@NO)))

与前一种写法区别为将获取流水号和更改流水号放到同一个事物中.
1

Gabriel - 茕茕白兔 东走西顾 衣不如新 人不如故 2013-07-08 回答

通过以上语句生成结果,效果预览如图
1

TravyLee - 尼玛!这哪是下雨,分明就是有人在泼水! 2013-07-09 回答


在学习中遇到这个问题
数据库里有编号字段
BH00001
BH00002
BH00003
BH00004
如何实现自动增长



--下面的代码生成长度为8的编号,编号以BH开头,其余6位为流水号。
--得到新编号的函数
CREATE FUNCTION f_NextBH()
RETURNS char(8)
AS
BEGIN
RETURN(SELECT 'BH'+RIGHT(1000001+ISNULL(RIGHT(MAX(BH),6),0),6) FROM tb WITH(XLOCK,PAGLOCK))
END
GO

--在表中应用函数
CREATE TABLE tb(
BH char(8) PRIMARY KEY DEFAULT dbo.f_NextBH(),
col int)

--插入资料
BEGIN TRAN
INSERT tb(col) VALUES(1)
INSERT tb(col) VALUES(2)
INSERT tb(col) VALUES(3)
DELETE tb WHERE col=3
INSERT tb(col) VALUES(4)
INSERT tb(BH,col) VALUES(dbo.f_NextBH(),14)
COMMIT TRAN

--显示结果
SELECT * FROM tb
/*--结果
BH col
---------------- -----------
BH000001 1
BH000002 2
BH000003 4
BH000004 14
--*/



create table tb
(id int identity,
name varchar(10),
code as 'BH'+right('0000'+cast(id as varchar),5))
go
insert tb(name) select 'A'
union all select 'B'
union all select 'C'
union all select 'D'

select * from tb

drop table tb

/*
id name code
----------- ---------- ------------
1 A BH00001
2 B BH00002
3 C BH00003
4 D BH00004

(所影响的行数为 4 行)
*/

要回复问题请先登录注册