SqlServer生成单号
物流系统难免跟单号打交道,单号可以在数据库中用函数生成,写存储过程时可以直接调用函数对订单进行操作:
首先附上需求:
Create FUNCTION [dbo].[Get_NO] () RETURNS VARCHAR(1000) BEGIN declare @NewApplyNo varchar(20)='' --当前表里最新单号 declare @NextApplyNo varchar(20)=''--待生成的申请单号 select TOP 1 @NewApplyNo=Apply_NO from T2_GT_POlist WHERE CHARINDEX(CONVERT(varchar(12),getdate(), 112),Apply_NO)>0 and DoType = 8 and Isvalid = 1 order by Indate desc if (isnull(@NewApplyNo,'')='')--今日第一个单 begin select @NextApplyNo='S'+CONVERT(varchar(12),getdate(), 112)+'001' end else begin select @NextApplyNo ='S'+CONVERT(varchar(12),getdate(), 112)+right('0000'+Convert(varchar(10),Convert(int,right(@NewApplyNo,3))+1),3) end return @NextApplyNo end
这是Sql中一个标量值函数的写法,其中用到的函数:
1、CharIndex()
判断一个字符串中是否包含另一个字符串,但是SQL SERVER中并没有像C#提供了Contains函数,不过SQL SERVER中提供了一个叫CHAEINDX的函数,顾名思义就是找到字符(char)的位置(index),既然能够知道所在的位置,当然就可以判断是否包含在其中了。
通过CHARINDEX如果能够找到对应的字符串,则返回该字符串位置,否则返回0。
CHARINDEX ( expressionToFind , expressionToSearch [ , start_location ] )
expressionToFind :目标字符串,就是想要找到的字符串,最大长度为8000 。
expressionToSearch :用于被查找的字符串。
start_location:开始查找的位置,为空时默认从第一位开始查找。
CHARINDEX(CONVERT(varchar(12),getdate(), 112),Apply_NO)>0
判断当前单号是否包含今天的时间。
其中先把今天时间通过convert()函数转化为单号的字符串格式(2021-05-28转换为“20210528”)
例如:
Select CONVERT(varchar(100), GETDATE(), 112);--20180108
其他需要的格式请参考:https://blog.csdn.net/qq_37528515/article/details/105647179
2、这里用到convert()函数:
CONVERT(data_type,expression[,style])
data_type:目标系统所提供的数据类型,如果转换时没有指定数据类型的长度,则 SQL Server 自动提供长度为 30。
expression:是任何有效的 Microsoft® SQL Server™ 表达式
style:【可选参数】日期格式样式,此样式一般在时间类型(datetime,smalldatetime)与字符串类型(nchar,nvarchar,char,varchar)相互转换的时候才用到
style 参数提供的数值确定了 datetime 数据的显示方式,年份可以显示为两位或四位数。默认情况下,SQL Server 将年份显示为两位数。若要显示包括世纪的四位数年份 (yyyy)(即使年份数据是使用两位数的年份格式存储的),请给 style 值加 100 以获得四位数的年份
单号和今天的日期匹配好了之后就可以生成单号了,不过在这之前还得判断是否为今天第几单,如果为上面CharIndex()的值为空的话就是第一单,如何判断为空还可以用到:
3、Isnull()函数:
isnull(value1,value2)
①value1与value2的数据类型必须一致。
②如果value1的值不为null,结果返回value1。
③如果value1为null,结果返回vaule2的值。vaule2是你设定的值。
if (isnull(@NewApplyNo,'')='')--今日第一个单 begin select @NextApplyNo='S'+CONVERT(varchar(12),getdate(), 112)+'001' end
第一单直接加上连接字符串即可,那么如果不是第一单呢?
else begin select @NextApplyNo ='S'+CONVERT(varchar(12),getdate(), 112)+right('0000'+Convert(varchar(10),Convert(int,right(@NewApplyNo,3))+1),3) end
就必须取最末尾的几位数值转为int类型加上1再转为字符串类型再连接上,这里取末尾的几位要用到:
4、Right()函数:
Right(str,n)
返回字符串str最右边的n个字符的字符串
right('0000'+Convert(varchar(10),Convert(int,right(@NewApplyNo,3))+1),3)
a= Convert(int,right(@NewApplyNo,3))+1 //将后边三位取出来转为int类型+1 002→003;
b = a 转为字符串类型;
right('0000'+b,3) //将字符串'0000'+'003'='0000003',再取后边三位003得出结果