对于如下声明的变量I和过程Test:
?
{DECLARE I INTEGER 1; ? CREATE PROCEDURE Test(INOUT I REFERENCE)
} |
?
?
当调用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树不会被清理的吧。
?