监视 CL 程序或过程中的消息

可以监视的消息是程序或过程中使用的每个 CL 命令发出的 *ESCAPE , *STATUS 和 *NOTIFY 消息。

注: 通过使用代码示例,您同意 代码许可证和免责声明信息的条款。

每个 IBM提供的命令在其帮助文档中标识其生成的异常消息。 您可以使用此信息来确定要在程序或过程中监视哪些消息。

异常消息包括通过过程或程序中的命令或通过另一过程或程序中的命令发送到 CL 过程或程序的调用消息队列的转义消息,通知消息和状态消息。 无法监视诊断消息。

使用 Monitor Message (MONMSG) 命令,您可以监视发送到调用消息队列的一条或多条消息,以了解该命令中指定的条件。 然后,可以使用 MONMSG 命令来指定如果条件存在,那么将运行 MONMSG 命令上指定的 CL 命令。 MONMSG 命令涉及的逻辑如下所示:

转义消息: 发送转义消息以告知过程或程序强制发送方结束的错误情况。 通过监视脱离消息,您可以执行纠正操作或清除并结束过程或程序。

状态或通知消息: 将发送状态和通知消息,以告知您的过程或程序没有足够严重的异常情况,以便发送方结束。 通过监视状态或通知消息,您的过程或程序可以检测到此情况,而不允许该功能继续。

您可以使用两个级别的 MONMSG 命令来监视消息:

  • 过程级别: 您可以通过在 CL 过程或程序中的最后一个声明命令之后立即指定 MONMSG 命令来监视程序或过程中的任何命令发送的转义,通知或状态消息。 这称为过程级 MONMSG 命令。 可以在过程或原始程序模型 (OPM) 程序中使用多达 100 个过程级别的 MONMSG 命令。 (CL 过程或 OPM 程序可包含总计 1000 个 MONMSG 命令。) 这使您能够以相同方式处理所有命令的同一脱离消息。 EXEC 参数是可选的,只能在此 EXEC 参数上指定 GOTO 命令。
  • 特定命令级别: 您可以通过在命令后立即指定 MONMSG 命令来监视由过程或程序中的特定命令发送的转义,通知或状态消息。 这称为命令级别 MONMSG 命令。 可以将多达 100 个命令级别的 MONMSG 命令用于单个命令。 这使您能够以不同的方式处理不同的脱离消息。

要监视转义,状态或通知消息,必须通过下列其中一种方法在 MONMSG 命令上指定消息的通用消息标识:

  • pppmmnn

    监视特定消息。 例如, MCH1211 是零分割脱离消息的消息标识。

  • pppmm00

    监视具有以特定许可程序 (ppp) 开头的通用消息标识的任何消息以及由 mm 指定的数字。 例如, CPF5100 指示将监视所有以 CPF51 开头的通知,状态和脱离消息。

  • ppp0000
    监视具有以特定许可程序 (ppp) 开头的通用消息标识的每条消息。 例如, CPF0000 指示将监视以 CPF 开头的所有通知,状态和脱离消息。
    注: 请勿在执行系统功能 (例如,安装或保存或复原整个系统) 时使用 MONMSG CPF0000 ,因为可能会丢失重要信息。
  • CPF9999

    监视功能检查消息。 如果未监视错误消息,那么它将变为 CPF9999 (函数检查)。

注: 通常,在监视时,监视器还可以控制何时发送通知和状态消息。

除了按消息标识监视脱离消息外,还可以将您在 MONMSG 命令中指定的字符串与消息中发送的消息数据进行比较。 例如,以下命令监视文件 MYFILE 的脱离消息 (CPF5101)。 当程序发送 CPF5101 消息时,将该文件的名称指定为消息数据。


MONMSG MSGID(CPF5101) CMPDTA(MYFILE) EXEC(GOTO EOJ)

比较数据可以长达 28 个字符,比较从消息数据的第一个字段的第一个字符开始。 如果比较数据与消息数据匹配,那么将运行 EXEC 参数上指定的操作。

MONMSG 命令上的 EXEC 参数指定如何处理脱离消息。 除了 PGM , ENDPGM , IF , ELSE , DCL , DCLF , ENDDO 和 MONMSG 以外的任何命令都可以在 EXEC 参数上指定。 您可以在 EXEC 参数上指定 DO 命令,并运行 do 组中的命令。 当命令或执行组 (在 EXEC 参数上) 已运行时,控制权将返回到过程或程序中发送脱离消息的命令之后的命令。 但是,如果指定 GOTO 或 RETURN 命令,那么控制权不会返回。 如果未指定 EXEC 参数,那么将忽略脱离消息,并且程序或过程将继续。

以下显示了正在监视零分割脱离消息的 Change Variable (CHGVAR) 命令的示例,消息标识为 MCH1211:


CHGVAR VAR(&A) VALUE(&A / &B)
MONMSG MSGID(MCH1211) EXEC(CHGVAR VAR(&A) VALUE(1))

变量 &A 的值将变为 &A 除以 &B 的值。 如果 &B 等于 0,则无法进行除法运算,并向存储过程发送除数为零的转义信息。 此时,&A 的值将变为 1(如 EXEC 参数所指定)。 也可以测试 &B 是否为零,如果不为零,才执行除法运算。 这比尝试对脱离消息进行操作和监视更有效。

在以下示例中,过程在 Check Object (CHKOBJ) 命令上监视脱离消息 CPF9801 (找不到对象消息):


          PGM
          CHKOBJ LIB1/PGMA *PGM
          MONMSG MSGID(CPF9801) EXEC(GOTO NOTFOUND)
          CALL LIB1/PGMA
          RETURN
NOTFOUND: CALL FIX001 /* PGMA Not Found Routine */
          ENDPGM

以下 CL 过程包含两个 Call (CALL) 命令以及用于 CPF0001的过程级别 MONMSG 命令。 如果无法成功完成 Call (CALL) 命令,那么会出现此脱离消息。 如果任一 CALL 命令失败,那么该过程将发送完成消息并结束。


        PGM
        MONMSG MSGID(CPF0001) EXEC(GOTO ERROR)
        CALL PROGA
        CALL PROGB
        RETURN
ERROR:  SNDPGMMSG MSG('A CALL command failed') MSGTYPE(*COMP)
        ENDPGM

如果未在过程级别 MONMSG 命令上对 EXEC 参数进行编码,那么将忽略 MONMSG 命令处理的任何脱离消息。 如果在除 IF 命令的情况以外的任何命令上出现脱离消息,那么该过程将继续处理未发生脱离消息时下一个运行的命令。 如果在 IF 命令的条件下出现脱离消息,那么该过程将继续处理,就像 IF 命令的条件为 false 一样。 以下示例说明了在过程中的不同点发生脱离消息时发生的情况:


PGM
DCL &A TYPE(*DEC) LEN(5 0)
DCL &B TYPE(*DEC) LEN(5 0)
MONMSG MSGID(CPF0001 MCH1211)
CALL PGMA PARM(&A &B)
IF (&A/&B *EQ 5) THEN(CALL PGMB)
ELSE CALL PGMC
CALL PGMD
ENDPGM

根据发生脱离消息的位置,会发生以下情况:

  • 如果在调用 PGMA 时发生 CPF0001 ,那么该过程将在 IF 命令上恢复处理。
  • 如果在 IF 命令上发生 MCH1211 (除以 0) ,那么 IF 条件将被视为 false ,并且该过程将继续处理对 PGMC 的调用。
  • 如果在调用 PGMB 或 PGMC 时发生 CPF0001 ,那么该过程将继续处理对 PGMD 的调用。
  • 如果在调用 PGMD 时发生 CPF0001 ,那么该过程将使用 ENDPGM 命令恢复处理,这将导致返回到调用过程。

您还可以监视要由过程或程序中的特定命令以及另一个命令发送的同一脱离消息。 这需要两个 MONMSG 命令。 一个 MONMSG 命令跟在需要对脱离消息进行特殊处理的命令之后; 对于该命令,将在发送脱离消息时使用此 MONMSG 命令。 另一个 MONMSG 命令跟在最后一个声明命令之后,因此对于所有其他命令,将使用此 MONMSG 命令。

MONMSG 命令仅适用于对其进行编码的 CL 过程或 OPM 程序。 一个过程中的 MONMSG 命令不适用于另一个过程,即使这两个过程都是同一程序的一部分。 每个命令的联机帮助和文档都包含针对该命令发出的转义消息,通知消息和状态消息的列表。 您还应该保留已定义的所有消息的列表。

注: 由于消息的渗透方式,前一段对于 ILE 过程不成立。 系统要求 MONMSG 处理发送到过程的任何脱离消息。 否则,消息将对调用堆栈进行整理,直到找到具有 MONMSG 来处理该调用堆栈或命中控制边界的过程为止。