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的提交与调用对象无关,是独立的一个单元。