JCL - 條件處理



作業輸入系統使用兩種方法在 JCL 中執行條件處理。作業完成後,將根據執行狀態設定返回碼。返回碼可以是 0(成功執行)到 4095(非零表示錯誤條件)之間的數字。最常見的約定值是:

  • 0 = 正常 -一切正常

  • 4 = 警告 - 出現輕微錯誤或問題。

  • 8 = 錯誤 - 出現重大錯誤或問題。

  • 12 = 嚴重錯誤 - 出現主要錯誤或問題,結果不可靠。

  • 16 = 終止錯誤 - 出現非常嚴重的問題,請勿使用結果。

可以使用 **COND** 引數和 **IF-THEN-ELSE** 結構來控制作業步驟的執行,本教程已對此進行了解釋。

COND 引數

可以在 JCL 的 JOB 或 EXEC 語句中編寫 **COND** 引數。它是對前面作業步驟返回碼的測試。如果測試結果為真,則當前作業步驟的執行將被跳過。跳過只是省略作業步驟,而不是異常終止。單個測試中最多可以組合八個條件。

語法

以下是 JCL COND 引數的基本語法:

COND=(rc,logical-operator)
or
COND=(rc,logical-operator,stepname)
or
COND=EVEN
or 
COND=ONLY

以下是所用引數的說明:

  • **rc**: 這是返回碼

  • **邏輯運算子**: 可以是 GT(大於)、GE(大於或等於)、EQ(等於)、LT(小於)、LE(小於或等於)或 NE(不等於)。

  • **stepname**: 這是測試中使用其返回碼的作業步驟。

最後兩個條件 (a) COND=EVEN 和 (b) COND=ONLY,已在本教程中進行了解釋。

COND 可以寫在 JOB 語句或 EXEC 語句中,這兩種情況下其行為都不同,如下所述:

JOB 語句中的 COND

當在 JOB 語句中編寫 COND 時,將對每個作業步驟進行條件測試。當在任何特定作業步驟中條件為真時,它將被跳過,以及其後的作業步驟。以下是一個示例:

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID,COND=(5,LE)
//*
//STEP10 EXEC PGM=FIRSTP  
//* STEP10 executes without any test being performed.

//STEP20 EXEC PGM=SECONDP 
//* STEP20 is bypassed, if RC of STEP10 is 5 or above. 
//* Say STEP10 ends with RC4 and hence test is false. 
//* So STEP20 executes and lets say it ends with RC16.

//STEP30 EXEC PGM=SORT
//* STEP30 is bypassed since 5 <= 16.

EXEC 語句中的 COND

當在作業步驟的 EXEC 語句中編寫 COND 並發現其為真時,只有該作業步驟將被跳過,執行將從下一個作業步驟繼續。

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//STP01 EXEC PGM=SORT
//* Assuming STP01 ends with RC0.

//STP02 EXEC PGM=MYCOBB,COND=(0,EQ,STP01)
//* In STP02, condition evaluates to TRUE and step bypassed.

//STP03 EXEC PGM=IEBGENER,COND=((10,LT,STP01),(10,GT,STP02))
//* In STP03, first condition fails and hence STP03 executes. 
//* Since STP02 is bypassed, the condition (10,GT,STP02) in 
//* STP03 is not tested.

COND=EVEN

當編寫 COND=EVEN 時,即使任何之前的步驟異常終止,當前作業步驟也會執行。如果與 COND=EVEN 一起編寫任何其他 RC 條件,則如果沒有任何 RC 條件為真,則作業步驟將執行。

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//STP01 EXEC PGM=SORT
//* Assuming STP01 ends with RC0.

//STP02 EXEC PGM=MYCOBB,COND=(0,EQ,STP01)
//* In STP02, condition evaluates to TRUE and step bypassed.

//STP03 EXEC PGM=IEBGENER,COND=((10,LT,STP01),EVEN)
//* In STP03, condition (10,LT,STP01) evaluates to true,
//* hence the step is bypassed.

COND=ONLY

當編寫 COND=ONLY 時,只有當任何之前的步驟異常終止時,當前作業步驟才會執行。如果與 COND=ONLY 一起編寫任何其他 RC 條件,則如果沒有任何 RC 條件為真並且任何之前的作業步驟異常失敗,則作業步驟將執行。

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//STP01 EXEC PGM=SORT
//* Assuming STP01 ends with RC0.

//STP02 EXEC PGM=MYCOBB,COND=(4,EQ,STP01)
//* In STP02, condition evaluates to FALSE, step is executed 
//* and assume the step abends.

//STP03 EXEC PGM=IEBGENER,COND=((0,EQ,STP01),ONLY)
//* In STP03, though the STP02 abends, the condition 
//* (0,EQ,STP01) is met. Hence STP03 is bypassed.

IF-THEN-ELSE 結構

控制作業處理的另一種方法是使用 IF-THEN-ELSE 結構。這提供了更靈活和使用者友好的條件處理方式。

語法

以下是 JCL IF-THEN-ELSE 結構的基本語法:

//name IF condition THEN
list of statements //* action to be taken when condition is true
//name ELSE 
list of statements //* action to be taken when condition is false
//name ENDIF

以下是上述 IF-THEN-ELSE 結構中使用術語的說明:

  • **name**: 這是可選的,名稱可以有 1 到 8 個字母數字字元,以字母、#、$ 或 @ 開頭。

  • **Condition**: 條件將具有以下格式:**KEYWORD OPERATOR VALUE**,其中 **KEYWORDS** 可以是 RC(返回碼)、ABENDCC(系統或使用者完成程式碼)、ABEND、RUN(步驟已開始執行)。**OPERATOR** 可以是邏輯運算子(AND (&)、OR (|))或關係運算符 (<、<=、>、>=、<>)。

示例

以下是一個簡單的示例,展示了 IF-THEN-ELSE 的用法:

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//PRC1   PROC
//PST1	   EXEC PGM=SORT
//PST2	   EXEC PGM=IEBGENER
//       PEND
//STP01  EXEC PGM=SORT 
//IF1    IF STP01.RC = 0 THEN
//STP02     EXEC PGM=MYCOBB1,PARM=123
//       ENDIF
//IF2    IF STP01.RUN THEN
//STP03a    EXEC PGM=IEBGENER
//STP03b    EXEC PGM=SORT
//       ENDIF
//IF3    IF STP03b.!ABEND THEN
//STP04     EXEC PGM=MYCOBB1,PARM=456
//       ELSE
//       ENDIF
//IF4    IF (STP01.RC = 0 & STP02.RC <= 4) THEN
//STP05     EXEC PROC=PRC1
//       ENDIF
//IF5    IF STP05.PRC1.PST1.ABEND THEN
//STP06     EXEC PGM=MYABD
//       ELSE
//STP07     EXEC PGM=SORT
//       ENDIF

讓我們嘗試檢視上述程式,以便更詳細地理解它:

  • 在 IF1 中測試 STP01 的返回碼。如果為 0,則執行 STP02。否則,處理將轉到下一個 IF 語句 (IF2)。

  • 在 IF2 中,如果 STP01 已開始執行,則執行 STP03a 和 STP03b。

  • 在 IF3 中,如果 STP03b 未 ABEND,則執行 STP04。在 ELSE 中,沒有語句。這稱為 NULL ELSE 語句。

  • 在 IF4 中,如果 STP01.RC = 0 和 STP02.RC <=4 為真,則執行 STP05。

  • 在 IF5 中,如果作業步驟 STP05 中過程 PRC1 中的 proc-step PST1 ABEND,則執行 STP06。否則執行 STP07。

  • 如果 IF4 的值為假,則不執行 STP05。在這種情況下,不測試 IF5,也不執行步驟 STP06、STP07。

如果作業異常終止(例如使用者取消作業、作業時間到期或資料集向後引用被跳過的步驟),則不會執行 IF-THEN-ELSE。

設定檢查點

可以使用 **SYSCKEOV**(這是一個 DD 語句)在 JCL 程式中設定檢查點資料集。

**CHKPT** 是在 DD 語句中為多卷 QSAM 資料集編寫的引數。當 CHKPT 編碼為 CHKPT=EOV 時,會在輸入/輸出多卷資料集的每個卷結束時將檢查點寫入 SYSCKEOV 語句中指定的資料集。

//CHKSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//STP01     EXEC PGM=MYCOBB
//SYSCKEOV  DD DSNAME=SAMPLE.CHK,DISP=MOD
//IN1       DD DSN=SAMPLE.IN,DISP=SHR
//OUT1      DD DSN=SAMPLE.OUT,DISP=(,CATLG,CATLG)
//          CHKPT=EOV,LRECL=80,RECFM=FB	

在上面的示例中,在輸出資料集 SAMPLE.OUT 的每個卷結束時,都會在資料集 SAMPLE.CHK 中寫入檢查點。

重新啟動處理

可以使用 **RD 引數** 自動方式或使用 **RESTART 引數** 手動方式重新啟動處理。

**RD 引數** 編寫在 JOB 或 EXEC 語句中,它有助於自動 JOB/STEP 重新啟動,並且可以儲存四個值之一:R、RNC、NR 或 NC。

  • **RD=R** 允許自動重新啟動,並考慮 DD 語句的 CHKPT 引數中編寫的檢查點。

  • **RD=RNC** 允許自動重新啟動,但會覆蓋(忽略)CHKPT 引數。

  • **RD=NR** 指定作業/步驟無法自動重新啟動。但是,當使用 RESTART 引數手動重新啟動時,將考慮 CHKPT 引數(如有)。

  • **RD=NC** 禁止自動重新啟動和檢查點處理。

如果只需要對特定 abend 程式碼進行自動重新啟動,則可以在 IBM 系統 parmlib 庫的 **SCHEDxx** 成員中指定。

**RESTART 引數** 編寫在 JOB 或 EXEC 語句中,它有助於在作業失敗後手動重新啟動 JOB/STEP。RESTART 可以與 checkid 結合使用,checkid 是在 SYSCKEOV DD 語句中編碼的資料集中寫入的檢查點。當編碼 checkid 時,應編碼 SYSCHK DD 語句以引用 JOBLIB 語句(如有)後的檢查點資料集,否則應在 JOB 語句後引用。

//CHKSAMP JOB CLASS=6,NOTIFY=&SYSUID,RESTART=(STP01,chk5)
//*
//SYSCHK    DD DSN=SAMPLE.CHK,DISP=OLD
//STP01     EXEC PGM=MYCOBB
//*SYSCKEOV	DD DSNAME=SAMPLE.CHK,DISP=MOD
//IN1       DD DSN=SAMPLE.IN,DISP=SHR
//OUT1      DD DSN=SAMPLE.OUT,DISP=(,CATLG,CATLG)
//          CHKPT=EOV,LRECL=80,RECFM=FB	

在上面的示例中,chk5 是 checkid,即 STP01 在 checkpoint5 處重新啟動。請注意,已新增 SYSCHK 語句,並且在“設定檢查點”部分中解釋的先前程式中已註釋掉 SYSCKEOV 語句。

廣告