无重复编号

jted 2009-03-30 02:44:19
如:
数据库表 a_tp 有字段2个 id(自增) BH(编号)

a_tp.BH 字段 数据格式:20090315001

时间+001 002 003 ....

条件:
1.如果当前日期无数据。则新编号为 时间+001 如:20090330001
2.如果当前日期有数据,如已有数据 20090330001 20090330002 则得到新编号20090330003
关键:已有数据,可能存在的几种情况:
A:20090330001 20090330002 则得到新编号20090330003
B: 20090330002 20090330004 则得到新编号20090330001
C: 20090330001 20090330004 则得到新编号20090330002


要求:查询a_tp.BH得到符合条件的新编号并插入该新记录。
...全文
119 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
wang_quan_li 2009-04-15
  • 打赏
  • 举报
回复
//自动编号,带断号检测补号功能 20090212 add by wangquan
function createBH(){
$contact_no = date("Y").date("m").date("d"); //编号规则
$sql = "select contact_no from cx_contact where contact_no like '".$contact_no."%' order by contact_no asc";
$sql1 = "select contact_no from cx_contact where contact_no like '".$contact_no."%' order by contact_no desc";
$this->db->query($sql1);
if($this->db->next_record()){
$num=substr($this->db->Record["contact_no"],-3); //此处的数字3表示编号位数(001 002 003 .... )
//echo 'num='.$num;
if($num <> $this->db->num_rows){
$num = 0;
$this->db->query($sql);
while($this->db->next_record()){
$tnum = substr($this->db->Record["contact_no"],-3);
//echo 'tnum='.$tnum;
if($tnum - $num ==1)
$num = $tnum;
else
break;
//echo 'num='.$num;
}
}
}
else
$num=0;
//echo 'num='.$num;
$contact_no = $contact_no.sprintf("%'03s", $num+1);
return $contact_no;
}
调用这个函数得到的$contact_no就是你要的编号
lonelyriver 2009-03-30
  • 打赏
  • 举报
回复
学习
ten789 2009-03-30
  • 打赏
  • 举报
回复
自增INT就行 假如初始ID为2009032900001
插入后取回ID 如果不是今天的编号再UPDATE一次

UPDATE的概率不是很高 每天只有1次而已
TR@SOE 2009-03-30
  • 打赏
  • 举报
回复
不简单啊,还要查漏补缺啊:

[code=INIFile]C: 20090330001 20090330004 则得到新编号20090330002 [/code]

能不能请LZ告诉我们,这么做的意义何在?这个编号到底有什么意义?和实际中的什么相对应?

永远不要为了创造一个单一ID而创造一个单一ID。

程序猿之殇 2009-03-30
  • 打赏
  • 举报
回复
建议用数据表或者xml来保存最后日期的最新编号,
新的记录产生时,从这个表或者xml里获取最新编号,这样每次都是递加并且是最新的.

你每次搜索带有N多记录的数据表,还要进行字符串操作,效率太低.


总哈哈 2009-03-30
  • 打赏
  • 举报
回复
SELECT 这里写查0001的代码 FROM table WHERE left(BH, 6)='2009033';(注意函数不一定正确,这里只给出思路) 这样会查出一部分,然后得到一系列的数字。0001 0002 0003.。。。。这样完了以后把它们去掉0变成数字,因为你只希望是从1开始的数据,那么从1开始一个一个在里面找,第一个找不出的数字则为你要找的数据
Dogfish 2009-03-30
  • 打赏
  • 举报
回复
不多的话,可以... ...

select top 1 a.bh, b.id from 
(
select '20090330001' as bh
union
select '20090330002' as bh
union
select '20090330003' as bh
union
select '20090330004' as bh
union
select '20090330005' as bh
) a
left outer join a_tp b on a.bh = b.bh
where b.id is null
order by a.bh
frederic_zhao 2009-03-30
  • 打赏
  • 举报
回复
特殊要求的话楼主可以写一个存储函数,专门获取当前的数据库中不存在的最小序号。

说一下我的思路,欢迎讨论

定义自增判断变量

做一个游标 declare cur1 CURSOR FOR SELECT BH FROM a_tp ;

打开游标into进游标变量;

WHILE ( 游标变量 is not null) DO

判断变量与截取处理后的游标中编号对比

不相等的时候应该就是当前最小的返回这个值

判断变量+1

end WHILE
TR@SOE 2009-03-30
  • 打赏
  • 举报
回复
另外,上述的思路虽然不能避免跳号,但是是否有跳号是可以检查出来的:

如果剩余编号的数量不等于(当前最大编号-当前最小编号+1),而且最后的一个编号(三位的话就是999)还存在就说明肯定有跳号的。
TR@SOE 2009-03-30
  • 打赏
  • 举报
回复
如果你现在的问题在于,已经有了那么多的数据,要开始查漏补缺的话,我建议你只能进行“人肉”工作:针对每天的记录,进行排查。而且,对于过去的日期的整理也没有什么意义,不做也罢。

对于将来可能出现的跳漏号情况,我给你一个思路:

1. 在服务器上设置一个cron工作,每天零点零分开始清空一个“可用编号”表,并重新添加001-999的记录;
2. 用户输入ID的时候,首先判断可用编号表中该编号是否可用:
2.1 如果可用,删除该编号;
2.2 如果不可用,说明当日已经有其它用户用了该编号,系统可以建议当前表中的最小编号给用户;
3. 结合当前日期给出可用的编号;

这种方法,还是不能保证某天不会出现跳号情况。所以,我不知道这么做的意义何在。

最好的处理方法,是和你的客户谈谈,到底这么做的意义何在,是想避免什么问题。
LIHY70 2009-03-30
  • 打赏
  • 举报
回复
我来听听有什么好办法~~·
jted 2009-03-30
  • 打赏
  • 举报
回复
首先谢谢各位大大的关注,指点。。。

[Quote=引用 4 楼 TR@SOE 的回复:]
不简单啊,还要查漏补缺啊:


INIFile codeC: 20090330001 20090330004 则得到新编号20090330002



能不能请LZ告诉我们,这么做的意义何在?这个编号到底有什么意义?和实际中的什么相对应?

永远不要为了创造一个单一ID而创造一个单一ID。
[/Quote]
我明白TR@SOE的意思,其实编号只要不重复就ok了,可以取最大+1的方式来确定新编号。但制作的时候,客户突然有这样的要求,要求查漏补缺。从效率上希望能找到个较合理的方式来完成这个功能。

to:jakey9826 ten789
要求查漏补缺的

to:dogfish
谢谢你的帮助,但得有个通用的处理方式。

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧