编号如何解决(200分)

  • 主题发起人 主题发起人 mawp402
  • 开始时间 开始时间
M

mawp402

Unregistered / Unconfirmed
GUEST, unregistred user!
程序在增加新记录时产生一个编号,这个编号的值组成如下:
编号=字符串变量1+字符串变量2+年份+五位编号(如00001);
客户端每增加一条新记录时,都产生一个这样的编号,该编号要在客户端实时
显示,当多个用户同时操作时,第一个用户从表中查询并组合得到了一个编号,
第二个用户也从表中查询并组合得到了一个编号,这两个编号可能会重复,
提交时就会报错。这个问题该如何解决?
注:年份+五位编号(如00001) 从表中查询得到,并且五位编号(如00001)在从表
中查询的时候根据字符串变量1和字符串变量2为条件查询,字符串变量1和字符
串变量2的不同值得到的最大五位编号(如00001)也会不同,不同的用户操作时,
符串变量1和字符串变量2的值会不相同
请多指教
 
报错就让他报出来阿,让他手工修改阿
丁大是将报错信息汉化阿
 
你的字符变量1和字符变量2是否根据客户端确定的??也就是说不是同一台机器上使用,生成的
字符变量就一定不同
??
 
设定一个因子,客户取一次编号改因子就加一,所以每个人取得值会不同
 
这个问题一直让我很头痛,现在我的程序里就让他报错,重新生成
我曾经请教过其他人,可以有这样的解决方法:
1:锁定库表,导致同一时间只有一个客户端录入(没有试过,:)
2:在数据库里建一个存储最大编号的表,客户端每增加记录时从这个表中取
这个表采取表级锁定(应该可行)
 
1、如果如你所言,不同的用户操作时,符串变量1和字符串变量2的值会不相同,
那不就解决了,怎么会重复呢?
2、或者你可以新建一个表sysinfo(itemName,itemValue),用来存储当前的编号,每个用户只
要取一次,就将这个编号+1返回客户端,不管这个编号是否真正存进去。
 
这位兄台!
以上各位的看法都有道理,但是我认为还是利用数据库的触发器比较好!
不知兄台认为如何!
 
是呀,不同的用户那
字符串1和字符串2就不一样呀
怎么会重复
 
让他报错,然后重新生成
 
2、或者你可以新建一个表sysinfo(itemName,itemValue),用来存储当前的编号,每个用户只
要取一次,就将这个编号+1返回客户端,不管这个编号是否真正存进去。
这个方法最可靠,
注意: 作成数据库的存储过程,取数据时,会自动生成事务,阻止其他进程
 
在网络上多人同时编码时,能自动编码且不重复。
语 法:
NetAutoSeqNo(cSequenceTable:String;
cDataBaseName:String;
cTable:String;
oField:TField;
cKind:String):String
参 数:cSequenceTable(型别:String)编号文件资料表名称,若无则Def为SEQUENCE
cDataBaseName (型别:字符串)编号文件所在的Alias
cTable(型别:String)所要编号的资料表名称 (使用在相同字段名称,
不同table时,若无传'')
oField(型别:Field) 所要编号的字段
cKind(型别:字符串)编号的前置值
传 回 值:字符串
使用说明:选择您需要网络自动编码的字段,请在Tag的属性输入以下的程序
#NETAUTONO;B;C;YYMMDD


说明:当第一次执行此一函式时,它会在指定的Alias(第二个参数)下建立一个实体数据库(名称就是第一个参数,若没有编号档,会以SEQUENCE为名称),分别有NAME、KIND、SEQUENCE等字段。NAME代表你要编码的字段,KIND代表类别,SEQUENCE代表流水号编到第几码了,比如说我要ORDERNO字段编码,而我要表达出这订单是某年月的第几笔订单,所以NAME字段是ORDERNO,KIND是年+月,例如8705,SEQUENCE是已有了几笔订单。以【图3-1】来说,如果我要在78年02月增加一笔订单,NetAutoSeqNo函式就会找到此Record,知道7802此类编号已编到第6笔了,所以NetAutoSeqNo会编出7802007的号码,然后将6改成7。



【图3-1】
注意事项:
1. 前编及后编问题:所谓前编是指NetAutoSeqNo函式写在OnNewRecord事件中;而后编是写在 键中,也就是做ApplyUpData的地方。两者各有优缺点如下
OnNewRecord
优点 按新增键马上就能看到编码。 可以放弃储存,不会有跳号情况发生。
缺点 这笔Record必须要储存不能放弃,因为Sequence数据库中的流水号已加1,若放弃下次新增时将会跳号。 按新增键不能马上就能看到编码,需按确定键之后才显示。
 
使用数据库的 BEFOREPOST 事件,我在我的呼叫中心软件中就是这样实现的且
没有出现过错误,但使用SQL的储存过程确不行.
 
为什么要从表中调那个5位号?让他自增不就行了。
 
自己写Sequence啊。每次都调用NextVal...
 
服务端建一个存储过程,客户端的编号由该存储过程统一提供
 
其实这个问题已经有不少人问了,你完全可以参考一下以往的贴子。
我的理解: 你应该是根据变量1 和 变量2 来定位一个库或者一个种类
然后生成一个五位定长的编号,加以组合,作为一个入库
编号。
其实这里最难的一点也就是控制五位定长编号的产生与不可
重复性。
我现行的办法是这样(假设这个自动产生的号码不允许遗漏):
建立一个号码库(与你所说的最大号码库异曲同工),该库可以用触发器来
定期生成,比如查询其记录数不可低于多少个。
每个用户要提交之前就取一个号码到前端来,并标识该已经不可用。取号的
过程如果要求一定自动的话,可以设成递归形式的:
取号 ----------
| |
| 延迟1秒
------------- |
| | |
成功 失败-----

保存数据时,把所取号码从号码库中删除。
这样即可自动生成编号,而且可以保证其唯一性及连续性。
不过其取号的递归做法我不赞成,如果处理不当可能会有负面影响
 
补充一点: 这种先生成编号的做法其实很不明智,如果将这个过程后移
至保存时生成,也就是说当要保存数据时再生成,这样冲突
的机率将会大大减小
 
我现在的做法:客户端新增单据时,编号处显示“新单据”,保存时由中间层的应用服
务器生成你所要的单据编号,组合进Delta数据包中,提交给数据库服务器,如果成功,再
将Delta数据包回传给客户端,并组合和合并客户端ClientDataSet的Delta属性,此时即可
马上打印此单据了。
 
我的做法和娃娃所说的类似,未保存时先取到一个编号给用户看,在真正保存时再重新生成一个,
如果存不了,提示用户再保存一次,在多用户使用时基本不会有什么问题
 
字复串+整数
每获得编号一次就触发一次整数+1
 
后退
顶部