Genexus 如何实现获得数据库表中的最大值及多用户的控制(z)

例子:我们新增物资内容后,保存到数据库中,系统需要保存一个唯一的记录流水号。
我们设计Trn如下
  TrnPrd
        ( * PrdID       N(8.0)
                 PrdCod   V(40)
                 PrdNam  V(40)
                 PrdCom  V(40)
                 PrdNum  V(40)
       )

我们可以设计 PrdID为主键 , 并且 设置 PrdID 的 autonumber = true ,step = 1,即prdId是自增类型

这样 我们新增记录时,就不需考虑PrdID

PrcInsPrd:

New

       PrdCod = &PrdCod
       PrdName = &PrdName
       ..................

EndNew

保存时,oracle数据库会自动写上prdid。
这样有好处,也有很不好,就是我们不能很有效的控制prdid。比如说表trnprd导出到备份后,还原数据时,prdid都已经变了,就是说关键字都变了,但是具体的内容没有变,这个对这个表有对应关系的话,就可以就不正确了,因为原来的主键都变了。

所以我们一般不把prdid设为 autonumber

这样的话,我们就需要手工得到prdid的最大值

prcgetMaxPrdID:
Rules:Pram(out:&MaxPrdID);


Source:

for each (PrdID)
        &MaxPrdID = PrdID + 1
        exit
       when none
                 &MaxPrdID = 1
endfor

PrcInsPrd:

New
        PrdID = PprcGetMaxPrdID.Udp()//得到最大值
        PrdName = &PrdName
        ..........
EndNew


这样就可以了,但是很多人问我,如果客户端都同时得到相同的最大值,那保存后会出现什么情况呢?
这个情况在多用户系统中是很常见的。出现这个情况,肯定时谁最先提交到数据库,谁就保存成功,否则就不能保存,因为数据库中已经存在相同的prdid了。

为了解决这个问题,我们一般是这个处理的

PrcInPrd:

do  ‘NewARecord’


Sub 'NewARecord'

        New
                 PrdID = PprcGetMaxPrdID.Udp()//得到最大值
                 PrdName = &PrdName
                 ..........

                 when duplicate//当重复时,再次做New操作,直到不能重复为止,这个地方很关键哦
                        do ‘NewARecord’
         EndNew

EndSub

 

你可能感兴趣的:(oracle,数据库,each)