关于DELPHI用ADO连接数据库插入的问题?

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

其实解决的办法是多样的,我以前也做的很多这类的事情,方法也不很复杂。可惜啊,没有分咯,呵呵……