How can I test for an error code in a CLIP or PCL when using the TRANSFER command?

Document ID : KB000054702
Last Modified Date : 14/02/2018
Show Technical Document Details

Description

The TRANSFER part works in that if the entity does not exist in EMR zone I get error code 0005 and reason code 0023. If it does exist in EMR zone I get error code 0000 reason code 0000.

This is fine but I am unable to test for Error: 0005/0023. Here is an extract of the CLIP coding:

  //          IF ASRRID.TZONE<<F,L>> = 'PRD' 
  //             IF ASRRID.IZONE<<F,L>> NE 'EMR' 
  //                DEFINE LOCAL(INPUTUFL.UFL) 
  //                SET INPUTUFL.SCHEME = 'ZONE' 
  //                SET INPUTUFL.ZONE = 'EMR' 
  //                SET INPUTUFL.ENAME = '&ENAME'
// SET INPUTUFL.ETYPE = '&ETYPE' // SET INPUTUFL.SGNAM = 'UNUSED' // DEFINE LOCAL(OUTPUTUFL.UFL) // SET OUTPUTUFL.SCHEME = 'MVS' // SET OUTPUTUFL.DSORG = 'PS' // TRANSFER INPUT=INPUTUFL.UFL,OUTPUT=OUTPUTUFL.UFL //* //* ERROR WILL BE 0005 AND REASON 0023 IF ENTITY DOES NOT EXIST IN EMR //* ERROR WILL BE 0000 AND REASON 0000 IF ENTITY DOES EXIST IN EMR //* ANY OTHER CODE WILL ALSO FAIL PACKAGE AND NEEDS TO BE INVESTIGATED //* // DISPLAY 'HELPC' // DISPLAY 'ERROR = &TRANSFER_CONTROL.ERROR ENDOF' // DISPLAY 'REASON = &TRANSFER_CONTROL.REASON ENDOF' // DISPLAY '&PCLLSTCC' //* SET ERRCODE = TRANSFER_CONTROL.ERROR<<F,L>> //* SET RESCODE = TRANSFER_CONTROL.REASON<<F,L>> //* DISPLAY 'ERRCODE = &ERRCODE' //* DISPLAY 'RESCODE = &RESCODE' // IF TRANSFER_CONTROL.ERROR INCLUDES '0005' AND C // TRANSFER_CONTROL.REASON INCLUDES '0023' // DISPLAY 'EMR BYPASS' // ELSE // DISPLAY 'EMR EXISTS' // SET ASRRED_STOP(&N) = C // 'A VERSION EXISTS IN EMR ZONE ERROR &TRANSFER_CONTROL.ERROR C // REASON &TRANSFER_CONTROL.REASON' // ENDIF // ENDIF // ENDIF

This should result in EMR BYPASS as the entity I am testing does not exist in EMR zone and the codes are 0005 and 0023. What I am getting is EMR EXISTS which is wrong.

I've also tried PCLLSTCC but that is set to 0 whether the error code is 0000 or 0005 which goes against what the manual sas.

The ERRCODE and RESCODE that are commented out didn't work either as I got this error:

  SUPERFLUOUS CHARACTERS AFTER END OF EXPRESSION 
  TEXT OF COMMAND IN ERROR: 
  // SET ERRCODE = TRANSFER_ CONTROL.ERROR<<F,L>> 

This is what the displays in the SYSLOG with the above code:

  1/CLIP16; HELPC 
  1/CLIP16; ERROR = 0005 ENDOF 
  1/CLIP16; REASON = 0023                           ENDOF 
  1/CLIP16; 0 
  1/CLIP16; EMR EXISTS 

Solution

When a variable is referenced directly by name in PCL (rather than by using symbolic substitution) and the variable's value contains only numeric digits, PCL treats it as a numeric (integer) value rather than as an alphanumeric expression (string).

Consequently, when the error code is 0005, PCL interprets:

  • IF TRANSFER_CONTROL.ERROR INCLUDES '0005'

as meaning:

  • IF 5 INCLUDES '0005'

This is why the test fails and returns the false EMR EXISTS.

Similarly, the <<F,L>> substring qualifier can only be used with alphanumeric expressions, which is why it fails when preceded by a variable containing only numeric digits, which is seen as a numeric expression.

There are two possible ways around this:

  1. Pre-concatenate something alphabetic at the start, to guarantee an alphanumeric expression, prior to attempting to eliminate trailing spaces. For example:
      //               SET ERRCODE = 'X':TRANSFER_CONTROL.ERROR 
      //               SET ERRCODE = ERRCODE<<2,L>> 
      //               SET RESCODE = 'X':TRANSFER_CONTROL.REASON 
      //               SET RESCODE = RESCODE<<2,L>> 

    The <<2,L>> above will eliminate both the leading X and trailing spaces. \

  2. Use symbolic substitution to form an explicit alphanumeric expression. For example,
      //          SET ERRCODE='&TRANSFER_CONTROL.ERROR'<<F,L>> 
      //          SET RESCODE='&TRANSFER_CONTROL.REASON'<<F,L>> 

    Either way, we then need to use:
     //          IF ERRCODE=5 

    But NOT :
    // IF ERRCODE='0005' (because ERRCODE is now numeric and thus treated as integer 5, which does not equal the string '0005')

    NOR :
    // IF ERRCODE INCLUDES '0005' (because ERRCODE is now numeric and thus treated as integer 5, which does not include the string '0005')

Solution A is recommended, for two reasons:

  1. It's simpler

  2. It's not adversely affected if either variable should happen to contain a quote or ampersand, unlike solution B.

    Therefore, it is suggested the PCL after the TRANSFER command, should be changed to:
      //               SET ERRCODE = 'X':TRANSFER_CONTROL.ERROR 
      //               SET ERRCODE = ERRCODE<<2,L>> 
      //               SET RESCODE = 'X':TRANSFER_CONTROL.REASON 
      //               SET RESCODE = RESCODE<<2,L>> 
      //               DISPLAY 'ERRCODE = &ERRCODE' 
      //               DISPLAY 'RESCODE = &RESCODE' 
      //               IF ERRCODE=5 AND RESCODE=23 
      //                DISPLAY 'EMR BYPASS' 
      //                   ELSE 
      //                DISPLAY 'EMR EXISTS' 
      //                   SET ASRRED_STOP(&N) =                             C 
      //    'A VERSION EXISTS IN EMR ZONE ERROR &TRANSFER_CONTROL.ERROR      C 
      //     REASON &TRANSFER_CONTROL.REASON' 
      //                ENDIF