现在商场需要一个销售单流水号生成器,该流水号的组成结构是这样的:
SA100323000001=SA+年的后2位+月+日+6位流水号
请写一个函数 FN_GEN_SANO(@DATE DATETIME,@COUNT)
其中,@DATE是完整的日期,@COUNT是个数。
例如,参数分别是‘2007-03-01’,2那么
EXEC DBO.FN_GEN_SANO(‘2007-03-01’,2)得出的结果是
SANO
SA070301000001
SA070301000002

解决方案 »

  1.   

    --(4)生成流水号   
    if object_id('tb') is not null drop table tb   
    drop function dbo.FC_Next   
    create function dbo.FC_Next()   
    returns char(8)   
    as  
    begin   
         return (select 'BH'+right(1000001+isnull(right(max(BH),6),0),6) from tb)   
    end    
    create table tb   
    (   
      BH char(8) primary key default dbo.FC_Next(),   
      col int  
    )   
    select * from tb   
      
    begin tran   
    insert into tb (col) values (1)   
    insert into tb (col) values (2)   
    insert into tb(BH,col) values (dbo.FC_Next(),14)   
    commit tran   
    select * from tb  
    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ws_hgo/archive/2009/02/10/3872714.aspx
      

  2.   

    --编号表
    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
    GOCREATE TABLE tb(BH char(12))
    --获取 CG 的新编号
    DECLARE @bh char(12)
    EXEC p_NextBH 'CG','2005-1-1',@bh OUT
    SELECT @bh
    --结果: CG0501010001EXEC p_NextBH 'CG','2005-1-1',@bh OUT
    SELECT @bh
    --结果: CG0501010002EXEC p_NextBH 'CG','2005-1-2',@bh OUT
    SELECT @bh
    --结果: CG0501020001EXEC p_NextBH 'CG','2005-2-2',@bh OUT
    SELECT @bh
    --结果: CG0402020001EXEC p_NextBH 'CG','2004-2-2',@bh OUT
    SELECT @bh
    --结果: CG0402020001
    GO
      

  3.   

    --以下代码生成的编号长度为12,前6位为日期信息,格式为YYMMDD,后6位为流水号。
    --创建得到当前日期的视图
    CREATE VIEW v_GetDate
    AS
    SELECT dt=CONVERT(CHAR(6),GETDATE(),12)
    GO--得到新编号的函数
    CREATE FUNCTION f_NextBH()
    RETURNS char(12)
    AS
    BEGIN
    DECLARE @dt CHAR(6)
    SELECT @dt=dt FROM v_GetDate
    RETURN(
    SELECT @dt+RIGHT(1000001+ISNULL(RIGHT(MAX(BH),6),0),6) 
    FROM tb WITH(XLOCK,PAGLOCK)
    WHERE BH like @dt+'%')
    END
    GO--在表中应用函数
    CREATE TABLE tb(
    BH char(12) PRIMARY KEY DEFAULT dbo.f_NextBH(),
    col int)--插入资料
    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)--显示结果
    SELECT * FROM tb
    /*--结果
    BH           col 
    ------------------- ----------- 
    050405000001  1
    050405000002  2
    050405000003  4
    050405000004  14
    --*/
      

  4.   

    select
      'sa'+right(year(@s),2)+'0'+ltrim(month(@s))+'0'+ltrim(day(@s))+RIGHT(1000001+ISNULL(RIGHT(MAX(col),6),0),6)
    from
      tb
      

  5.   

    没事,写了一个
    drop table tb1
    go
    create table tb1   
    (   
      BH varchar(20) 
    )   
    insert into tb1 (bh) values ('SA201202000001')   
    godrop proc FN_GEN_SANO
    go
    create proc dbo.FN_GEN_SANO(@d datetime,@c int)   
    as  
    begin   
    declare @max varchar(20)
    declare @i int
    DECLARE @tmp TABLE (BH varchar(20))  set @i=1
    select @max = max(BH) from tb1 where left(BH,8)='SA'+convert(varchar(6),@d,12)
    if @max is null 
    begin
    set @max='SA'+convert(varchar(6),@d,12)+'000000'
    endwhile @i<=@c
    begin
    insert into @tmp(BH) 
    values( 'SA'+convert(varchar(6),@d,12)+convert(varchar(6),right((convert(numeric(6),right(@max,6))+100000000+@i),6)) )
    set @i=@i+1
    end 
    select * from @tmp
    end    
    godeclare @d datetime
    declare @c intset @d='2020-12-2'
    set @c=5
    exec dbo.FN_GEN_SANO @d,@c
    (所影响的行数为 1 行)
    (所影响的行数为 1 行)
    (所影响的行数为 1 行)
    (所影响的行数为 1 行)
    (所影响的行数为 1 行)BH                   
    -------------------- 
    SA201202000002
    SA201202000003
    SA201202000004
    SA201202000005
    SA201202000006(所影响的行数为 5 行)
      

  6.   

    select rtrim(replace(CONVERT(nvarCHAR(8),GETDATE(),11),'/',''))+str(100000+1,6)