记录冲突问题(200)

  • 主题发起人 CHINESEWHOAMI
  • 开始时间
C

CHINESEWHOAMI

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大师好!以下一段代码为由电脑产生最新的单据单号,如果不是同时间按一切OK,问题出在两部电脑同时按[保存]按钮时,会出现单据单号一模一样,不知要如何解决?还请各位大师指点下.谢谢! ADOQUERY1.SQL.TEXT:='SELECT TOP 1 SHDH FROM CGSHD_S WHERE (DE_ IS NULL OR DE_='+''''+''+''''+') ORDER BY SHDH DESC'; ADOQUERY1.Open; IF ADOQUERY1.RecordCount=0 THEN EDIT18.TEXT:='YH000001' ELSE EDIT18.TEXT:='YH'+DUPESTRING('0',6-LENGTH(TRIM(INTTOSTR(STRTOINT(COPY(ADOQUERY1.FIELDBYNAME('SHDH').AsString,3,6))+1))))+TRIM(INTTOSTR(STRTOINT(COPY(ADOQUERY1.FIELDBYNAME('SHDH').AsString,3,6))+1)); ADOQUERY1.Close;
 
利用自增自段产生唯一号,再添加其他附加信息
 
或是将单号做主键!!!另外一点,也是我们当年碰到过的,就是:不要在adoquery的afterinsert或是点“增加”按钮时产生单号,而要在beforepost中产生单号,这样,重复的机率会小的多,但还是要加上主键约束才行。
 
TO:delphi2011用标识号会有一个问题,即当记录被删除时,其单号就会跳过,而要求是单号必须是连续的。TO:zbdzjx 不知能否详细点。谢谢!^_^
 
只要删单,就不可能连续,难道把10天前的单删除了,新单还要填补空缺?
 
TO:delphi2011 有时操作员在操作时,会把当前的记录删除掉(即最新的记录,都还没发生关联的)
 
新增的时候可能生成两张单据的单号是一样的比如:0001,保存的时候,自己写一个存储过程取单号,那么保存后两张单据的单号会是0001,0002.至于具体怎么实现自己想吧。
 
月薪15-50K招聘it administratorKnowledge in DCOM or COM+ (which is in essence the same thing) Knowledge in IIS version 5 or higher Knowledge of Troubleshooting worker processes in IIS 希望10月上旬立即开始上班 地点:北京 三元桥 薪资:面议(能力好的话salary不是问题) 要求:英文要好,读写听说均流利 简历发送邮箱:hr_grace@126.com。电话和我联系13947437351
 
先max(单据单号),然后单据单号这样就不会重复
 
TO:仙界蚂蚁 能否详细一点。谢谢!
 
每次添加纪录时,先判断单号的最大值,然后把最大值+1,这样就不会重复了
 
TO:仙界蚂蚁这个方法单机操作可能不出问题,如果刚好出现2台机同时按保存,max(单据单号)得到了相同的结果,保存的时候则出现LZ说的现象。
 
呵呵,应该不会重复,我试过了,发生同一时分秒保存数据的的几率太小了
 
1、你将你写的语句放在adoquery的beforepost中去运行,这样,在保存时就直接生成单号,马上保存,单号相同的可能非常小。2、你在表中将shdh设成主键或是建唯一索引,这样,如果单号相同,后保存的一个会报错。3、如果你不想断号,就不能用你的语句了。用类似下面的语句:for i:=1 to 999999 dobegin adoquery1.close; adoquery1.sql.text:='select shdh from cgshd_s where shdh =''YH'+formatfloat('000000',i)+''' and (DE_ IS NULL OR DE_='+''''+''+''''+')'; adoquery1.open; if adoquery1.recordcount=0 then break;end;edit18.text:='YH'+formatfloat('000000',i);上面语句的意思就是:从1号单据开始,一张一张的在表中找,如果某一个单号找不到,就用这个单号。但这也不能完全避免断号,因为假如当前是全部连号的,你删除了其中一个,再也不新建了,就断号了,除非删除后会将其它的单据号码变更,但这是不合理的。但如果很少删除单据,增加单据的可能多,就基本上避免了断号了。
 
TO:仙界蚂蚁你说的方法我以前的公司用过,在几十个人同时操作时,一个月会有十次不到的错误发生。
 
用事务,提交失败后,提示用户系统忙,重试!
 
我们是这么处理的,把单据号单独存在一个表,这个表同时保存单据号的格式,比如:前缀yyyyMMdd,后缀5位(也就是该天的顺序号)。生成单据号时,取顺序号出来,再对其+1更新处理。单据号在单据表也是主键,因为取的时候更新,间隔很小,基本上不会重复,就是重复,因为主键的关系,也会保存不了单据。
 
楼上的作法我听朋友说过,他们是因为表的数据量太大了,所以我之前提出的方法就不太适用了。这样做的好处就是取单号的速度快了。为了防止重号,在取单号时,先锁定表,取出单号后,再加1,再保存,再释放表。
 
给你点提示,多台电脑同时访问数据库的时候,在任何一个时刻只能允许一台电脑访问,你要做个防冲突的机制,如果同时按下的话要保证一个成功,一个退出,我做过这方面的,还比较成功的
 
ZGH777所说的和锁定表的方法都可以
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
493
import
I
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
449
import
I
顶部