当前位置: 代码迷 >> SQL >> 关于ESQL中调用参数为INOUT REFERENCE类型过程会出错的有关问题浅析
  详细解决方案

关于ESQL中调用参数为INOUT REFERENCE类型过程会出错的有关问题浅析

热度:32   发布时间:2016-05-05 13:16:36.0
关于ESQL中调用参数为INOUT REFERENCE类型过程会出错的问题浅析

对于如下声明的变量I和过程Test:

?

{DECLARE I INTEGER 1;

?

CREATE PROCEDURE Test(INOUT I REFERENCE)
?BEGIN


??SET I = I + 1;
??
??RETURN;
?END;

}

?

?

当调用CALL Test(I);时执行到RUTURN时会抛出异常,不光当I是INTEGER类型时会这样,我试过当I是ROW类型的时候也一样会抛异常,但是如果参数I为IN REFERENCE类型或INOUT INTEGER类型时调用Test不会出问题,或者I引用的是Environment的子树时也不会出问题。

异常栈信息如下:

?

ExceptionList
?RecoverableException
???File:CHARACTER:F:\build\S000_P\src\DataFlowEngine\ImbDataFlowNode.cpp
???Line:INTEGER:739
???Function:CHARACTER:ImbDataFlowNode::createExceptionList
???Type:CHARACTER:ComIbmMQInputNode
???Name:CHARACTER:mySchema/MyMsgFlow#FCMComposite_1_1
???Label:CHARACTER:mySchema.MyMsgFlow.QIn
???Catalog:CHARACTER:BIPv610
???Severity:INTEGER:3
???Number:INTEGER:2230
???Text:CHARACTER:Node throwing exception
???RecoverableException
?????File:CHARACTER:F:\build\S000_P\src\DataFlowEngine\ImbComputeNode.cpp
?????Line:INTEGER:464
?????Function:CHARACTER:ImbComputeNode::evaluate
?????Type:CHARACTER:ComIbmComputeNode
?????Name:CHARACTER:mySchema/MyMsgFlow#FCMComposite_1_7
?????Label:CHARACTER:mySchema.MyMsgFlow.8583ToSoap
?????Catalog:CHARACTER:BIPv610
?????Severity:INTEGER:3
?????Number:INTEGER:2230
?????Text:CHARACTER:Caught exception and rethrowing
?????RecoverableException
???????File:CHARACTER:F:\build\S000_P\src\DataFlowEngine\ImbRdl\ImbRdlStatementGroup.cpp
???????Line:INTEGER:602
???????Function:CHARACTER:SqlStatementGroup::execute
???????Type:CHARACTER:ComIbmComputeNode
???????Name:CHARACTER:mySchema/MyMsgFlow#FCMComposite_1_7
???????Label:CHARACTER:mySchema.MyMsgFlow.8583ToSoap
???????Catalog:CHARACTER:BIPv610
???????Severity:INTEGER:3
???????Number:INTEGER:2488
???????Text:CHARACTER:Error detected, rethrowing
???????Insert
?????????Type:INTEGER:5
?????????Text:CHARACTER:mySchema.MyMsgFlow_8583ToSoap.Main
???????Insert
?????????Type:INTEGER:5
?????????Text:CHARACTER:6.3
???????Insert
?????????Type:INTEGER:5
?????????Text:CHARACTER:Test(I);
???????RecoverableException
?????????File:CHARACTER:F:\build\S000_P\src\DataFlowEngine\ImbRdl\ImbRdlRoutine.cpp
?????????Line:INTEGER:1466
?????????Function:CHARACTER:SqlRoutine::clearDownChildEnv
?????????Type:CHARACTER:ComIbmComputeNode
?????????Name:CHARACTER:mySchema/MyMsgFlow#FCMComposite_1_7
?????????Label:CHARACTER:mySchema.MyMsgFlow.8583ToSoap
?????????Catalog:CHARACTER:BIPv610
?????????Severity:INTEGER:3
?????????Number:INTEGER:2933
?????????Text:CHARACTER:
?????????Insert
???????????Type:INTEGER:5
???????????Text:CHARACTER:I

?

这个问题昨天发现的,今天才想明白是因为什么。可以注意到异常栈最后一层中有个SqlRoutine::clearDownChildEnv,从字面理解它是清理"child"环境,再想想过程Test的参数I是INOUT REFERENCE类型,说明I既是引用其它变量的,又需要传入和传出,关键是在这个引用和传出,引用可以很好理解,I和所引用的变量一样使用,对于传出,ESQL中定义OUT类型的变量是在RETURN时将变量返回,应该可以理解为C或JAVA中函数返回值时候的return I;若是这样,在返回之前,需要为返回值构建一个临时变量暂存,返回之后清理这个临时变量。若是一般的变量,它传入时是之传入,返回时清理它本身没有问题,而现在传入的参数是引用类型的,清理时就会出问题。这也就是为什么参数I为IN REFERENCE类型或INOUT INTEGER类型时调用Test不会出问题的原因。而对于I引用的是Environment子树时Call Test(I);也正常运行的原因也许是Environment树不会被清理的吧。

?

  相关解决方案