Kbase P15107: Error 3541 opening an SDO's query
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  10/16/2008 |
|
Status: Unverified
FACT(s) (Environment):
Progress 9.x
SYMPTOM(s):
Error opening an SDO's query
CAN-FIND is invalid within an OPEN QUERY. (3541)
SDO's query does contain a call to the CAN-FIND() function.
CAUSE:
Known limitation.
The 4GL OPEN QUERY statement does not allow calls to the CAN-FIND() function. As a consequence, you cannot define an SDO query containing the CAN-FIND() function either.
FIX:
The simplest workaround is to use inner or outer joins (depending on whether you are testing CAN-FIND() or NOT CAN-FIND()).
If CAN-FIND() is part of a more complex statement then you can define a Calculated Field (named, for example, canFindSurrogate) in the SDO, where the CAN-FIND() function and the rest of the expression can be moved. For example:
IF RowObject.Flag THEN
(CAN-FIND(FIRST SecondTable WHERE SecondTable.KeyField = RowObject.KeyField))
ELSE
TRUE
Please note that the Calculated Field refers to RowObject, not to the table for which the SDO is defined.
Then you can write an override for the SDO's openQuery() method as follows:
FUNCTION openQuery RETURNS LOGICAL
( /* parameter-definitions */ ) :
/*------------------------------------------------------------------------------
Purpose: Super Override to overcome the CAN-FIND() limitation.
Notes:
------------------------------------------------------------------------------*/
DEF VAR hDataHandle AS HANDLE.
DEF VAR lReturn AS LOGICAL.
DEF VAR lReturnSuper AS LOGICAL.
/* Code placed here will execute PRIOR to standard behavior. */ hDataHandle = DYNAMIC-FUNCTION("getDataHandle"). lReturn = hDataHandle:QUERY-PREPARE("FOR EACH RowObject WHERE RowObject.canFindSurrogate") NO-ERROR.
IF lReturn THEN hDataHandle:QUERY-OPEN().
lReturnSuper = SUPER( ).
IF lReturnSuper THEN DO: hDataHandle = DYNAMIC-FUNCTION("getDataHandle").
IF DYNAMIC-FUNCTION("getLastRowNum") EQ ? THEN
RUN fetchLast.
lReturn = hDataHandle:QUERY-PREPARE("FOR EACH RowObject WHERE RowObject.canFindSurrogate") NO-ERROR.
IF lReturn THEN hDataHandle:QUERY-OPEN().
END.
RETURN lReturnSuper.
END FUNCTION.
Because of the call to fetchLast, this solution is suggested only for small record sets.
Please note that this code is provided as is, without any guarantee that it will workin any given environment. Please test your code thoroughly before putting it into production. Please keep in mind that this code might not work in future ADM2 releases.