2024年4月12日发(作者:)
Genexus + Oracle应用中出现提取违反顺序的错误解决方法
一、 错误现象
1)在Gx9.0 Win 应用中
2)在Gx Ev Web应用中
“/
tEnvironment”应用程序中的服务器错
误。
ORA-01002:
提取违反顺序
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致
错误的出处的详细信息。
异常详细信息: Exception: ORA-01002: 提取违反顺序
源错误:
执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信
息确定有关异常原因和发生位置的信息。
堆栈跟踪:
[OracleException (0x80131938): ORA-01002: 提取违反顺序
]
rror(OciErrorHandle errorHandle,
Int32 rc) +190
ternal() +867
() +66
() +56
[GxADODataException: ORA-01002: 提取违反顺序
]
() +156
xt() +28
xt(Int32 cursor) +33
ePrivate() +318
.E121J2() +44
1J2() +1343
chEvents() +5
012() +2317
cute() +130
cute() +259
sRequest(HttpContext httpContext) +175
[Exception: GXApplication exception]
sRequest(HttpContext httpContext) +264
e()
+181
eStep(IExecutionStep step, Boolean&
completedSynchronously) +75
二、 分析原因
Web方式和win方式都会存在这种情况。
为什么会出现这样情况呢?
原因:
(1):在我们执行proc1时用到for each 更新数据时,每循环1次(当记录非常多的时
候才会发生)就提交数据(即在循环语句中放置commit了,不推荐在for each 语句
中在更新字段时放置commit或rollback)。
如:
TrnPeo:
*PeoCod N(4) 流水号,主键
PeoNam V(20) 姓名
ProUpdPeo :(设置commit = NO)
for each PeoCod
&PeoCod = PeoCod
peoNam = 'D' + &ng()//更新字段了
commit //在这里放了,很危险的哦
endfor
分析:为什么要放commit呢,原因在于我想更新1条记录就提交1次,
这样写虽然没有错,但是执行就会出现上面的情况,与您想要的结果不一样了.
当然推荐在for each 外放commit了.虽然放在for each 外面,这样的情
况当然不能出现上述情况,但是如果是数据量很大的时候,将会等大量的数据处
理后再最后提交的时间会很长,很浪费时间.
所以如果我们的业务需要我们更新1条,提交1条,怎么办呢?
我们转换一下思路
ProUpdPeo :(设置commit = NO)
for each PeoCod
&PeoCod = PeoCod
UpdPeoNam(&PeoCod)
Endfor
Proc:UpdPeoNam
Rules:&PeoCod
Event:
For each
Where PeoCod = &PeoCod
peoNam = 'E' + &ng()
EndFor
commit
(2)第2种情况是我们在Proc1 (commit = no)执行循环时,调用另外的
Proc2(commit = yes)的时候发生.(如果Proc1和Proc2都设置成commit = no当然也
没有问题,但有的业务还是需要Proc2提交.如我们取最大值的时候要保存当前最
大值,已经提交)
如Proc1:
for each PeoCod
&PeoCod = ()//得到最大流水号
peoNam = 'D' + &ng()
endfor
Proc2:
parm(out:&InvSeqMax);
//每次取最大序号,并保存
for each
&InvSeqMax = InvSeqMax + 1
InvSeqMax = &InvSeqMax
endfor
commit
TrnInv:
*InvSeq N(4) 主建
InvSeqMax N(4) 记录最大号
那如何解决呢?
这种情况只要设置Proc2 的逻辑单元就可以了
设置Luw=true后,该Proc的提交与调用对象无关,是独立的一个单元。
发布评论