
- JCL 教程
- JCL 首頁
- JCL - 概述
- JCL - 環境
- JCL - JOB 語句
- JCL - EXEC 語句
- JCL - DD 語句
- JCL - 基礎庫
- JCL - 過程
- JCL - 條件處理
- JCL - 定義資料集
- JCL - 輸入/輸出方法
- JCL - 執行 COBOL 程式
- JCL - 實用程式
- JCL - 基本排序技巧
- JCL 有用資源
- JCL - 常見問題解答
- JCL - 快速指南
- JCL - 有用資源
- JCL - 討論
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 語句。