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得出结果



原文地址:https://www.cnblogs.com/jf-ace/p/14823138.html