ACCESS数据库表sb2004结构如下
字段名:BM(文本)  NAME(文本)
记录:b20040001    A0001
  ....
      B20041000    A1000
我想用程序实现在中间插入一行记录,但是BM字段后面的编号要跟着改变
(要保持编号连续),如何实现这个功能呢?
我用for   do语句做了,但太慢了。在输入界面时要等时间很长。   

来自:qaz2003, 时间:2004-2-2 15:40:00, ID:2431656
我以前的程序中的一段,增加记录时,记录号自动变化。只供参考。
procedure Tform.insertClick(Sender: TObject);
var
x:integer;
j:integer;
i:integer;
begin
dbgrid1.columns[1].readonly:=false;
dbgrid1.columns[2].readonly:=false;
dbgrid1.columns[4].readonly:=false;
lzcdata.gzzebntb.edit;
x:=lzcdata.gzzebntb.fields[0].asinteger;
lzcdata.gzzebntb.Insert;
lzcdata.gzzebntb.fields[0].asinteger:=0;
j:=lzcdata.gzzebntb.RecordCount;
dbgrid1.setfocus;
if (application.MessageBox('在此纪录这前插入吗?',
'提示信息',MB_yesno+mb_defbutton2+MB_iconexclamation)=idyes) then
begin
if (x>=1) then
x:=x-1;
end;
lzcdata.gzzebntb.last;
for i:=x+2 to lzcdata.gzzebntb.recordcount do
begin
lzcdata.gzzebntb.edit;
lzcdata.gzzebntb.fields[0].asinteger:=j+1;
j:=j-1;
lzcdata.gzzebntb.prior;
end;
lzcdata.gzzebntb.first;
lzcdata.gzzebntb.edit;
lzcdata.gzzebntb.fields[0].asinteger:=x+1;
lzcdata.gzzebntb.post;
end;  

来自:sunnyahniu, 时间:2004-2-2 15:44:00, ID:2431662
还不太明白你的意思,
是不是说:b20040001之后是b20040002……  

来自:Rafe, 时间:2004-2-2 16:04:00, ID:2431713
说个例子你就明白了:
sb2004020001
sb2004020002
sb2004020003
sb2004020004<
sb2004020005
在sb2004020004当前插入记录时,自动生成一个编号:sb2004020004
后面的编号跟着改变,也就是要保持记录编号要顺着的。
sb2004020001
sb2004020002
sb2004020003
sb2004020004
sb2004020005
sb2004020006

  

来自:晓风月, 时间:2004-2-2 16:12:00, ID:2431734
可以记录下你要插入记录的当前编号,插入成功后,再用一条UPDATA语句更新记录编号
大于刚记录的这个编号的记录,这样速度很快。  

来自:PangBS, 时间:2004-2-2 16:24:00, ID:2431764
update bm set bm = bm + 1 where bm > 插入的
注:bm = bm + 1 可以想个办法,例如用copy截取  

来自:liwens, 时间:2004-2-2 16:28:00, ID:2431767
这样的更新是需要一条条UPDATE的,FOR循环太慢就试试WHILE循环,不同循环
语句的执行效率因编译器及数据类型而异,多试试;如果数据量很大建议改用
其它类型的数据库,因为这样的循环用存储过程来执行最合适了,而ACCESS好像不
支持存储过程;  

来自:huhaitaode, 时间:2004-2-2 16:29:00, ID:2431773
这样是不行的。
当数据量大的时候就会很慢很慢。为什么要编号连续呢?  

来自:wen00000000, 时间:2004-2-2 16:43:00, ID:2431809
晓风月的方法是可行的  

来自:myjane, 时间:2004-2-2 16:45:00, ID:2431814
自动编号不可修改.
自定议的编号可先排序(从大到小),来获得最大编号(第一条就是).  

来自:Kevinjoan, 时间:2004-2-2 16:47:00, ID:2431820
无论用那种循环都无法提高你的运行速度,这个问题的速度不是个语法问题,而是一个数据结构问题,本案的速度取决于你插入的位置,如果纪录长度为n,你插入的位置是纪录头,将消耗 n+1个计算周期,如果插入到纪录尾将消耗1个计算周期,可见插入到记录头是该算法的最坏情况,插入到纪录尾是该算法的最好情况,而平均情况是((n+1)-1)/2=n/2。
我不知道你具体处理的情况,一般解决这样的问题只有采用链表结构,无论插入在什么地方时间复杂度仅为3个计算周期。
    

来自:雪上霜, 时间:2004-2-2 16:48:00, ID:2431824
用存储过程吧,这样程序容易死机  

来自:Smartbbs, 时间:2004-2-2 17:03:00, ID:2431874
记下insert的最小记录号,等全部要insert的记录都好了之后,把所有记录号整理一遍  

来自:Rafe, 时间:2004-2-2 17:14:00, ID:2431919
那位高手给出具体的解决办法吧!  

来自:fangye, 时间:2004-2-2 17:54:00, ID:2432043
顺序不是大问题,只要 order by 就可以了
如果你的号可以改动的话,说明编号不中要对吗,只是新加 必须在中间对吗?
如果是这样的话你只要取出最大编号
在最大编号基础上添加一条记录
然后和中间号吗换一下就可以了,不需要循环呀  

来自:Rafe, 时间:2004-2-2 18:19:00, ID:2432079
如果对换的话,就有只有两条记录改动了,中间的编号就不连续了,中间就可能出间断的编号。  

来自:Rafe, 时间:2004-2-2 19:32:00, ID:2432196
还有高手吗?快快置顶啊
  

来自:app2001, 时间:2004-2-2 19:34:00, ID:2432200
我也认为如此,每次取当中最大的编号+1,做为下条记录的编号就中了,有这么麻烦的吗?  

来自:Rafe, 时间:2004-2-2 19:36:00, ID:2432206
我想要的是中间插入记录啊,又要保持编号连续啊  

来自:caihua, 时间:2004-2-2 19:46:00, ID:2432210
以下两条完全可以做到了.
比如插入 b20040022 :
update sb2004 set bm=bm+1
where bm>='b20040022'

insert into sb2004 (bm,name) values('b20040022','新插入')

  

来自:studier, 时间:2004-2-2 19:42:00, ID:2432211
这道题的解决方法很多,以上这些仁兄说的方法都可以,我感觉还是“Kevinjoan”这位仁兄说的最好,这实际上是你的数据库中数据的组织结构的一个问题,对于你给出表的BM字段的内容,你可以分成两个字段,一个是"date_year"字段来记录当前年份,一个id字段其值为INT型,并设定其值是自动添加的。这样如果你要用数据的时候就可以将date_year与id字段的内容组合起来进行编程。  

来自:Rafe, 时间:2004-2-2 19:48:00, ID:2432221
我认同studier的说法,我修改数据结构,试试能不能改善效率!
还有没有其它更好的方法,请继续发言,统统有分加!  

来自:caihua, 时间:2004-2-2 19:50:00, ID:2432227
Rafe,我上面的方法你不能用吗???  

来自:Rafe, 时间:2004-2-2 20:03:00, ID:2432260
我正在试紧,但bm是文本字段,而前面有个字母,好像不能相加啊!  

来自:Rafe, 时间:2004-2-2 20:42:00, ID:2432316
我按照caihua仁兄说法,写了以下程序:
query1.SQL.Clear;
  query1.sql.add('update sb2004 set bm=bm+1 where bm>="B2004010006"');
  query1.ExecSQL;
  query1.SQL.Clear;
  query1.sql.add('insert into sb2004 (bm,name) values("B2004010006","新插入")');
  query1.ExecSQL;
  query1.SQL.Clear;
  query1.sql.add('select * from sb2004 order by bm');
  query1.Open;

运行程序出现:'"标准表达式中数据类型不匹配"错误
把字段BM中的B去掉就运行没有错,效果还可以过得去
看来是要字段BM分开才行啊!
不知有无更好的办法不用把B去掉呢?高手快来拿分吧!最后机会了  

来自:Rafe, 时间:2004-2-3 0:37:00, ID:2432531
都加分了!谢谢大家!最后我用了caihua 方法,给合studier了一些想法,比较简单效率还可以接受吧!  

来自:Rafe, 时间:2004-2-3 0:45:00, ID:2432536
多人接受答案了。  

来自:sunnyahniu, 时间:2004-2-6 17:41:00, ID:2440437
这么快就散分了,其实,你的问题并没有解决,不信你以后就会知道。
1.你的字段是字符型,不可能有bm=bm+1能得到正确的结果
2.如果出现你删除中间记录,那么你前后的记录又没有连续
……
  

来自:Rafe, 时间:2004-2-6 23:09:00, ID:2440918
TO sunnyahniu,你说得对啊!文本字段BM=BM+1是得不到结果,还有删除时也不会连续,我增加多一个字段,就能实现了!但现在又出新的问题,就记录中有两种编号,而且都要连续..又出了麻烦了.如下:增加\删除都要保持连续啊!
b2004010001
b2004010002
b2004010003
b2004010004
b402004010001
b402004010002
b402004010003
b402004010004
  

来自:sunnyahniu, 时间:2004-2-7 11:00:00, ID:2441383
其实解决的办法是多样的,我以前也做的很多这类的事情,方法也不很复杂。可惜啊,没有分咯,呵呵……