麻烦大家帮忙解决@tmp_piaohao中piaohao输出问题,谢谢!/*
存储表@piaohao(字段,数据如下)
字段piaohao组成'CKD'+年+月+四位顺序号
说明:1)年,4位字符,获取系统当前时间生成
     2)月,2位字符,获取系统当前时间生成
     3)月的初始号为0001,递增+1,下月复为0001,后+1递增
*/
DECLARE @piaohao TABLE (piaohao char(13))
INSERT  @piaohao SELECT 'CKD2010100001'
UNION ALL        SELECT 'CKD2010100002'
UNION ALL        SELECT 'CKD2010100003'
UNION ALL        SELECT 'CKD2010100004'
UNION ALL        SELECT 'CKD2010100006'
UNION ALL        SELECT 'CKD2010100007'
UNION ALL        SELECT 'CKD2010100009'
UNION ALL        SELECT 'CKD2010100010'
/*示例数据
piaohao
-------------
CKD2010100001
CKD2010100002
CKD2010100003
CKD2010100004
CKD2010100006
CKD2010100007
CKD2010100009
CKD2010100010输出表@tmp_piaohao(字段如下)
DECLARE @tmp_piaohao TABLE (id int , caozy char(10) , piaohao char(13))说明:字段id      唯一键,+1递增
     字段caozy   操作员
     字段piaohao 根据@piaohao表数据生成示例数据
id          caozy      piaohao
----------- ---------- -------------
1           操作员1       CKD2010100005
2           操作员2       CKD2010100008
3           操作员3       CKD2010100011
4           操作员4       CKD2010100012操作过程:@tmp_piaohao根据id,caozy及SQL计算出的piaohao展现出来麻烦大家帮忙解决@tmp_piaohao中piaohao输出问题,谢谢:  说明: 
  1)存在断号情况,优先插入断号,即(CKD2010100005,CKD2010100008)
  2)无断号情况,piaohao +1递增方式插入(CKD2010100011)
  3)插入操作可能多人同时操作.最少1人,多时4人.
    即:
       多人操作情况               piaohao输出
       ----------------------------------------------
       1人同时操作        [1]CKD2010100005
       2人同时操作        [1]CKD2010100005,[2]CKD2010100008
       3人同时操作        [1]CKD2010100005,[2]CKD2010100008,[3]CKD2010100011
       4人同时操作        [1]CKD2010100005,[2]CKD2010100008,[3]CKD2010100011,[4]CKD2010100012    
*/

解决方案 »

  1.   

    看不清楚想干什么,究竟是操作员生成piaohao,还是piaohao生成操作员
      

  2.   

    就生成piaohao,id caozy 只是作为多人同时操作的判断条件而已.
      

  3.   


    DECLARE @piaohao TABLE (piaohao char(13))
    INSERT  @piaohao SELECT 'CKD2010100001'
    UNION ALL        SELECT 'CKD2010100002'
    UNION ALL        SELECT 'CKD2010100003'
    UNION ALL        SELECT 'CKD2010100004'
    UNION ALL        SELECT 'CKD2010100006'
    UNION ALL        SELECT 'CKD2010100007'
    UNION ALL        SELECT 'CKD2010100009'
    UNION ALL        SELECT 'CKD2010100010'
    DECLARE @tmp_piaohao TABLE (id int , caozy char(10) , piaohao char(13))
    insert into @tmp_piaohao
    values(1,'操作员1','CKD2010100005'),
    (2,'操作员2','CKD2010100008'),
    (3,'操作员3','CKD2010100011'),
    (4,'操作员4','CKD2010100012')declare @str nvarchar(100)=''
    select @str=@str+case when len(@str)>0 then ',' else ''end +'['+CONVERT(nvarchar(1),id)+']'+piaohao
    from @tmp_piaohao
    select convert(nvarchar(10),(select COUNT(1) from @tmp_piaohao))+'人同时操作' 多人操作情况 ,@str  piaohao输出
     多人操作情况 piaohao输出
    --------------------------------------------------
    4人同时操作 [1]CKD2010100005,[2]CKD2010100008,[3]CKD2010100011,[4]CKD2010100012是这样吗?
      

  4.   

    谢谢tangdunfeng,我要的不是这样的.
    @tmp_piaohao表,可能有多人同时操作,而其piaohao是由@piaohao表中的piaohao根据上面的规则计算得到的.
      

  5.   

    自个写了一个,感觉不太完善,请大教指导一下,谢谢!/*
           多人操作情况               piaohao输出
           ----------------------------------------------
           1人同时操作        [1]CKD2010100005
           2人同时操作        [1]CKD2010100005,[2]CKD2010100008
           3人同时操作        [1]CKD2010100005,[2]CKD2010100008,[3]CKD2010100011
           4人同时操作        [1]CKD2010100005,[2]CKD2010100008,[3]CKD2010100011,[4]CKD2010100012
    */
    --@tmp_piaohao示例表
    DECLARE @tmp_piaohao TABLE (id int , caozy char(10) , piaohao char(13))
    INSERT  @tmp_piaohao SELECT 1,'操作员1',''   --直接运行SQL得到 CKD2010100005
    UNION  ALL           SELECT 2,'操作员2',''   --填入CKD2010100005 ,运行SQL得到 CKD2010100008
    UNION  ALL           SELECT 3,'操作员3',''   --填入CKD2010100008 ,运行SQL得到 CKD2010100011
    UNION  ALL           SELECT 4,'操作员4',''   --填入CKD2010100011 ,运行SQL得到 CKD2010100012
    -----------------------------------------------------SQL代码-------------------------------------------------------- 
    --@piaohao示例表
    DECLARE @piaohao TABLE (piaohao char(13))
    INSERT  @piaohao SELECT 'CKD2010100001'
    UNION ALL        SELECT 'CKD2010100002'
    UNION ALL        SELECT 'CKD2010100003'
    UNION ALL        SELECT 'CKD2010100004'
    UNION ALL        SELECT 'CKD2010100006'
    UNION ALL        SELECT 'CKD2010100007'
    UNION ALL        SELECT 'CKD2010100009'
    UNION ALL        SELECT 'CKD2010100010'
    -----------------------------------------我做已解决的部分-----------------------------------------------------------
    DECLARE @P char(13)
    DECLARE @DATE DATETIME 
    DECLARE @YYYY VARCHAR(4) 
    DECLARE @MM   VARCHAR(2)  
    SET @DATE = GETDATE()             --系统当前日期
    SET @YYYY = DATEPART(yyyy, @DATE) --年,YYYY格式
    SET @MM   = DATEPART(mm, @DATE)   --月,MM格式
    --位数不够的前面补
    SET @YYYY = REPLICATE('0', 4 - LEN(@YYYY)) + @YYYY 
    SET @MM   = REPLICATE('0', 2 - LEN(@MM)) + @MM 
    --取出表中当前日期的已有的最大ID 
    SET @P = NULL
    --给@P 赋值当前日期的已有的最大
    SELECT TOP 1 @P = PIAOHAO FROM @piaohao ORDER BY PIAOHAO DESC 
    --如果本年本月没有单号
    ----------------------------------------------断号-----------------------------------------------------------------
    DECLARE @T  TABLE (PIAOHAO char(13))   --定义临时表,功能:按最大出库单号生成顺序单号
    DECLARE @TT TABLE (PIAOHAO char(13))   --定义临时表,功能:存储断号出库单号
    DECLARE @I int,@N int                  --临时变量,@I循环初始值,@N当前最大出库单号
    --求当前最大出库单号
    SELECT @N   = CONVERT(int,(SELECT MAX(SUBSTRING(PIAOHAO,4,10)) FROM @piaohao ))
    --初始本年本月出库单号
    SELECT @I   = CONVERT(int,(SELECT MAX(SUBSTRING(PIAOHAO,4,6))  FROM @piaohao )+ '0000')
    --循环填充顺序出库单号
    WHILE @i < @N
         BEGIN
              INSERT @T 
              SELECT 'CKD'+CONVERT(char(10),@I +1)
              SET @i = @I + 1
         END     
    --存储断号出库单号
    INSERT @TT 
    SELECT PIAOHAO FROM @T WHERE PIAOHAO NOT IN (SELECT PIAOHAO FROM @piaohao )
    ----------------------------------------------输出-----------------------------------------------------------------
    IF @P IS NULL 
       BEGIN
    --如果本年本月没有单号,则直接从开始编号
    SELECT @P = 'CKD'+(@YYYY+@MM+'0001')    
       END 
    ELSE  
       BEGIN
        --如果本年本月有单号
    DECLARE @NUM VARCHAR(8) 
    --取出最大的编号加上
    SET @NUM = CONVERT(VARCHAR, (CONVERT(INT, RIGHT(@P, 4)) + 1))
    --因为经过类型转换,丢失了高位的,需要补上
    SELECT @NUM = REPLICATE('0', 4 - LEN(@NUM)) + @NUM
    --最后返回日期加编号
    SELECT  @P= 'CKD'+@YYYY+@MM+ @NUM 
       END
    ----------------------------------------------号段-----------------------------------------------------------------
    --输出号段临时列表
    DECLARE @HD TABLE (piaohao char(13))
    INSERT @HD
    SELECT * FROM @TT  --断号
    UNION ALL 
    SELECT @P          --正常输出的号
    ----------------------------------------------判断-----------------------------------------------------------------
    IF @P = (SELECT MAX(piaohao) FROM @tmp_piaohao WHERE piaohao <> '' )
       BEGIN
            --当本月最大编号+1已经存在
            SELECT 'CKD'+@YYYY+@MM+ REPLICATE('0', 4 - LEN(CONVERT(VARCHAR, (CONVERT(INT, RIGHT(@P, 4)) + 1)))) + CONVERT(VARCHAR, (CONVERT(INT, RIGHT(@P, 4)) + 1))
       END 
    ELSE 
       BEGIN
            --未存在,最小的一个单号
    SELECT MIN(PIAOHAO) AS piaohao 
    FROM @HD 
    WHERE piaohao NOT IN (SELECT piaohao 
      FROM   @tmp_piaohao
      WHERE  piaohao<>'')   
       END 
      

  6.   

    最后的判断改为如下,那不管以后@piaohao 表里的piaohao 是否断号,都能正常运行了.----------------------------------------------判断-----------------------------------------------------------------
    DECLARE @t_P char(13)   --@tmp_piaohao 中最大票号
    SELECT @t_P = (SELECT MAX(piaohao) FROM @tmp_piaohao WHERE piaohao <> '' ) 
    --当@tmp_piaohao 中最大票号 = @piaohao 中最大票号 +1 时
    IF @P = @t_P 
       BEGIN
            --piaohao = @piaohao 中最大票号 +1 +1
            SELECT 'CKD'+@YYYY+@MM+ REPLICATE('0', 4 - LEN(CONVERT(VARCHAR, (CONVERT(INT, RIGHT(@P, 4)) + 1)))) + CONVERT(VARCHAR, (CONVERT(INT, RIGHT(@P, 4)) + 1)) AS piaohao
       END 
    ELSE 
       BEGIN
            --当@tmp_piaohao 中最大票号 > @piaohao 中最大票号 +1 时
            IF @t_P >  @P
               BEGIN
                    --piaohao = @tmp_piaohao 中最大票号 +1
                    SELECT 'CKD'+@YYYY+@MM+ REPLICATE('0', 4 - LEN(CONVERT(VARCHAR, (CONVERT(INT, RIGHT(@t_P, 4)) + 1)))) + CONVERT(VARCHAR, (CONVERT(INT, RIGHT(@t_P, 4)) + 1)) AS piaohao
               END 
            ELSE 
               BEGIN
    --未存在,最小的一个单号
    SELECT MIN(PIAOHAO) AS piaohao 
    FROM @HD 
    WHERE piaohao NOT IN (SELECT piaohao 
      FROM   @tmp_piaohao
      WHERE  piaohao<>'')            
               END            
       END 麻烦大家帮优化,或提供更好的解决方案,谢谢!
      

  7.   

    不好意思,过程没能描述清楚,导致关注这个贴的朋友都感觉有点晕,SORRY.@tmp_piaohao 表,当进入系统时,系统会把id,caozy自动插入到这个表里,而piaohao 原是系统自动生成的,但由于某些特殊情况的存在,产生了断号的情况,为解决这个问题,我模拟了这个场景出来.
    --@tmp_piaohao示例表
    DECLARE @tmp_piaohao TABLE (id int , caozy char(10) , piaohao char(13))
    INSERT  @tmp_piaohao SELECT 1,'操作员1',''   --直接运行SQL得到 CKD2010100005
    UNION  ALL           SELECT 2,'操作员2',''   --填入CKD2010100005 ,运行SQL得到 CKD2010100008
    UNION  ALL           SELECT 3,'操作员3',''   --填入CKD2010100008 ,运行SQL得到 CKD2010100011
    UNION  ALL           SELECT 4,'操作员4',''   --填入CKD2010100011 ,运行SQL得到 CKD2010100012
    当第一个人进入的时,@tmp_piaohao 插入 1,'操作员1','',再运行SQL计算piaohao 时,得到CKD2010100005 
    而第二个进入 前面已经有了一个 CKD2010100005 ,所以计算得到 CKD2010100008 .
    ..... 所以,只要能让piaohao 按规则输出便可以了.再次谢谢大家的关注,谢谢!