自动编号怎么写

时间:2022-08-09 06:02:08
  ckdbh:=FormatDateTime('yymmdd', Now);
  sqltxt := 'select top 1* from [wzck] order by ckid desc ';
  openadoquery(dmf.ADOQuery7, sqltxt);
  if dmf.ADOQuery7.RecordCount = 1 then
     begin
        //取出出库单编号,得到后5位的数,加00001,然后和当前日期累加;
        ckdbh:=ckdbh+inttostr(StrToInt(RightStr(dmf.ADOQuery7.FieldByName('ckdh').AsString,5))+00001);
     end
  else
     begin
        ckdbh:=ckdbh+'00001';
     end;
  end;

我现在需要的是这样编号:比如今天是2013.12.18,出库单的编号统一为13121800001,13121800002等等,第二天,也就是2013.12.19,入库商品编号统一变为13121900003,13121900004等等,我上面的程序到是可以实现这个功能。
我的问题是,如果2014年,就需要从日期+00001开始重新编码,也是每年都需要从日期+00001开始重新编码,请问这个我应该怎么做能实现。

14 个解决方案

#1


select isnull(max(right(bh,5)),0)+1 newbh  from tb
where left(bh,2)='13'

#2


不是很明白,你这个意思是自动累加1吧

#3


引用 2 楼 hanger1978 的回复:
不是很明白,你这个意思是自动累加1吧


取本年的最大id

#4


取表中本身中最大+1,通过条件去筛选。

#5


每次增加出库单时,判断当前的年份和数据库中最后一条记录中的年份是否一致,如一致则继续+1,如大于(或不一致)则重新从00001开始。
出库单的编号最好能手动修改,然后让它+1就行了。否则好像每次都得判断一下。

#6



select row_number() over (order by name) as rowid, sysobjects.[name] from sysobjects
select id=IDENTITY(int,1,1), sysobjects.[name] as name into dbo.Test_Table from sysobjects

#7


这个应该没什么大难度吧。一般自动生成代码,我都是在数据库当中储存最大号的。如果是单机版的,直接在数据库中建立一个表,储存年、流水号,每次生成的号码先取出当前的日期,然后最大号+1不就可以了。然后在每次生成新的号码之前判断一下年,如果和数据库中不等,改数据库中的年,然后流水号初始化。当然了,还有很多方法。如果不是单机版的,那么你要记得取服务器日期。

#8


楼上的方案只是针对单个记录的增加,如果批量增加的时候,你就会发现新增的记录编号是一样的。
还是把最大的编号保存一个表里面,每次这个表里面取最大的号码就不会有重复了。

#9


var
  tempYear,GetValue:string;
  begin
  ckdbh:=FormatDateTime('yymmdd', Now);
  tempyear :=foarmatdatetime('yy',now);// 获得当时的年份
  sqltxt := 'select top 1* from [wzck] order by ckid desc ';
  openadoquery(dmf.ADOQuery7, sqltxt);
  if dmf.ADOQuery7.RecordCount = 1 then
     begin
       getvalue :=trim(copy(dmf.adoquery7.fieldbyname('ckdh').asstring,0,4); //获得最大值的年份
       if getvalue =tempyear then   //当时本年的时候
       begin
         //取出出库单编号,得到后5位的数,加00001,然后和当前日期累加;
        ckdbh:=ckdbh+inttostr(StrToInt(RightStr(dmf.ADOQuery7.FieldByName('ckdh').AsString,5))+00001);
       end
       else //是新年的时候
       begin
          ckdbh:=ckdbh+'00001';
       end;
      end;
    end;

#10



在并发性很高的情况系max+1模式就会有问题。oracle里有Sequence可用。sqlserver里虽然没有Sequence,但也有牛人经过改造做出相同的功能。自己连接过去看吧

http://www.cnblogs.com/heekui/archive/2008/07/24/1250842.html

#11


引用 8 楼 nieshiao 的回复:
楼上的方案只是针对单个记录的增加,如果批量增加的时候,你就会发现新增的记录编号是一样的。
还是把最大的编号保存一个表里面,每次这个表里面取最大的号码就不会有重复了。
单个添加和批量添加都没有关系好吗!!都一样,是因为你只执行了一次代码! 还是把最大的编号保存一个表里面难道我不是这么写的? 自动编号怎么写

#12


引用 10 楼 fox600123 的回复:
在并发性很高的情况系max+1模式就会有问题。

每次保存或者提交的时候校验一次就可以了吧。

#13


引用 12 楼 i_am_a_fish 的回复:
Quote: 引用 10 楼 fox600123 的回复:


在并发性很高的情况系max+1模式就会有问题。

每次保存或者提交的时候校验一次就可以了吧。


呵呵,就是校验和保存提交那么一瞬间,哪怕是0.01毫秒,max值都可能会被别的用户改变
况且记录数达到百万级别,取max值也是以秒计算的
这种事,最好交给数据库去做,程序控制不了的。
oracle里有Sequence就是专门为解决高并发性导致主键冲突而设计的。

#14


这个你逻辑说的清楚 ,就那样实现就行了 你有什么困难吗,这个你取出来的ID 的年与系统比对下不对的话就从000001 开始,方法太多 了 如楼上所说这种想唯一的ID, 最好是数据库去做,SQL 自动增长,oracle 用的是序列,你也可以像ORACEL 那样用个表去记录最大值 想不重复就是SELECT 一次MAX +1 

#1


select isnull(max(right(bh,5)),0)+1 newbh  from tb
where left(bh,2)='13'

#2


不是很明白,你这个意思是自动累加1吧

#3


引用 2 楼 hanger1978 的回复:
不是很明白,你这个意思是自动累加1吧


取本年的最大id

#4


取表中本身中最大+1,通过条件去筛选。

#5


每次增加出库单时,判断当前的年份和数据库中最后一条记录中的年份是否一致,如一致则继续+1,如大于(或不一致)则重新从00001开始。
出库单的编号最好能手动修改,然后让它+1就行了。否则好像每次都得判断一下。

#6



select row_number() over (order by name) as rowid, sysobjects.[name] from sysobjects
select id=IDENTITY(int,1,1), sysobjects.[name] as name into dbo.Test_Table from sysobjects

#7


这个应该没什么大难度吧。一般自动生成代码,我都是在数据库当中储存最大号的。如果是单机版的,直接在数据库中建立一个表,储存年、流水号,每次生成的号码先取出当前的日期,然后最大号+1不就可以了。然后在每次生成新的号码之前判断一下年,如果和数据库中不等,改数据库中的年,然后流水号初始化。当然了,还有很多方法。如果不是单机版的,那么你要记得取服务器日期。

#8


楼上的方案只是针对单个记录的增加,如果批量增加的时候,你就会发现新增的记录编号是一样的。
还是把最大的编号保存一个表里面,每次这个表里面取最大的号码就不会有重复了。

#9


var
  tempYear,GetValue:string;
  begin
  ckdbh:=FormatDateTime('yymmdd', Now);
  tempyear :=foarmatdatetime('yy',now);// 获得当时的年份
  sqltxt := 'select top 1* from [wzck] order by ckid desc ';
  openadoquery(dmf.ADOQuery7, sqltxt);
  if dmf.ADOQuery7.RecordCount = 1 then
     begin
       getvalue :=trim(copy(dmf.adoquery7.fieldbyname('ckdh').asstring,0,4); //获得最大值的年份
       if getvalue =tempyear then   //当时本年的时候
       begin
         //取出出库单编号,得到后5位的数,加00001,然后和当前日期累加;
        ckdbh:=ckdbh+inttostr(StrToInt(RightStr(dmf.ADOQuery7.FieldByName('ckdh').AsString,5))+00001);
       end
       else //是新年的时候
       begin
          ckdbh:=ckdbh+'00001';
       end;
      end;
    end;

#10



在并发性很高的情况系max+1模式就会有问题。oracle里有Sequence可用。sqlserver里虽然没有Sequence,但也有牛人经过改造做出相同的功能。自己连接过去看吧

http://www.cnblogs.com/heekui/archive/2008/07/24/1250842.html

#11


引用 8 楼 nieshiao 的回复:
楼上的方案只是针对单个记录的增加,如果批量增加的时候,你就会发现新增的记录编号是一样的。
还是把最大的编号保存一个表里面,每次这个表里面取最大的号码就不会有重复了。
单个添加和批量添加都没有关系好吗!!都一样,是因为你只执行了一次代码! 还是把最大的编号保存一个表里面难道我不是这么写的? 自动编号怎么写

#12


引用 10 楼 fox600123 的回复:
在并发性很高的情况系max+1模式就会有问题。

每次保存或者提交的时候校验一次就可以了吧。

#13


引用 12 楼 i_am_a_fish 的回复:
Quote: 引用 10 楼 fox600123 的回复:


在并发性很高的情况系max+1模式就会有问题。

每次保存或者提交的时候校验一次就可以了吧。


呵呵,就是校验和保存提交那么一瞬间,哪怕是0.01毫秒,max值都可能会被别的用户改变
况且记录数达到百万级别,取max值也是以秒计算的
这种事,最好交给数据库去做,程序控制不了的。
oracle里有Sequence就是专门为解决高并发性导致主键冲突而设计的。

#14


这个你逻辑说的清楚 ,就那样实现就行了 你有什么困难吗,这个你取出来的ID 的年与系统比对下不对的话就从000001 开始,方法太多 了 如楼上所说这种想唯一的ID, 最好是数据库去做,SQL 自动增长,oracle 用的是序列,你也可以像ORACEL 那样用个表去记录最大值 想不重复就是SELECT 一次MAX +1