Chapter 27 Exercises: JCL Essentials for COBOL Programmers

Tier 1: Recall (Exercises 1-8)

Exercise 1: Statement Identification

Identify the type of each JCL statement below (JOB, EXEC, DD, Comment, Delimiter, or JCLLIB):

a)  //PAYROLL  JOB (ACCT01),'JANE DOE',CLASS=A
b)  //STEP010  EXEC PGM=IGYCRCTL
c)  //*  COMPILE THE PAYROLL PROGRAM
d)  //SYSLIB   DD  DSN=PROD.COPYLIB,DISP=SHR
e)  /*
f)  //MYLIBS   JCLLIB ORDER=(DEV.JCLLIB)
g)  //         DD  DSN=SYS1.COPYLIB,DISP=SHR
h)  //SYSIN    DD  *

Solution:

a) JOB statement -- begins a job and defines job-level attributes. b) EXEC statement -- identifies a program to execute (the COBOL compiler IGYCRCTL). c) Comment statement -- identified by //* in columns 1-3. d) DD statement -- defines a dataset (named SYSLIB). e) Delimiter statement -- marks the end of instream data. f) JCLLIB statement -- specifies procedure library search order. g) DD concatenation -- unnamed DD concatenated with the preceding SYSLIB. h) DD statement -- defines instream data (data follows within the JCL).


Exercise 2: DISP Parameter Interpretation

For each DISP parameter below, state: (1) the initial status, (2) what happens on normal completion, and (3) what happens on abnormal termination.

a)  DISP=SHR
b)  DISP=(NEW,CATLG,DELETE)
c)  DISP=(OLD,DELETE,KEEP)
d)  DISP=(MOD,CATLG,DELETE)
e)  DISP=(NEW,PASS)
f)  DISP=(OLD,KEEP,KEEP)

Solution:

a) DISP=SHR -- (1) Existing dataset, shared access. (2) KEEP (default for existing datasets). (3) KEEP (default).

b) DISP=(NEW,CATLG,DELETE) -- (1) Dataset does not exist; create it. (2) Keep and catalog. (3) Delete the dataset. This is the standard pattern for creating output files.

c) DISP=(OLD,DELETE,KEEP) -- (1) Existing dataset, exclusive access. (2) Delete the dataset. (3) Keep the dataset on failure (for diagnosis). Common for cleanup steps.

d) DISP=(MOD,CATLG,DELETE) -- (1) If cataloged, open for append; if not cataloged, treat as NEW. (2) Keep and catalog. (3) Delete. Used for appending to existing files or creating new ones.

e) DISP=(NEW,PASS) -- (1) Create new dataset. (2) Pass to a subsequent step (temporary). (3) DELETE (default abnormal for NEW). The dataset exists only until the job ends or a later step gives it a final disposition.

f) DISP=(OLD,KEEP,KEEP) -- (1) Existing dataset, exclusive access. (2) Keep. (3) Keep. The dataset is preserved regardless of outcome.


Exercise 3: Space Calculation

A COBOL program produces an output file with 500,000 fixed-length records, each 250 bytes long, with RECFM=FB and BLKSIZE=27750 (111 records per block).

Calculate: a) Total file size in bytes b) Total file size in megabytes c) Number of tracks needed (1 track = 56,664 bytes on 3390) d) Number of cylinders needed (1 cylinder = 15 tracks on 3390) e) Write the SPACE parameter with a 25% safety margin, using cylinders

Solution:

a) 500,000 records * 250 bytes = 125,000,000 bytes

b) 125,000,000 / 1,048,576 = approximately 119.2 MB

c) 500,000 records / 111 records per block = 4,505 blocks (rounded up). Each track holds floor(56,664 / 27,750) = 2 blocks. 4,505 / 2 = 2,253 tracks (rounded up).

d) 2,253 tracks / 15 tracks per cylinder = 151 cylinders (rounded up).

e) With 25% safety margin: 151 * 1.25 = 189 cylinders. Use a primary of 150 with secondary of 40:

SPACE=(CYL,(150,40),RLSE)

Exercise 4: Compiler Return Codes

A COBOL compile-link-go job produces the following return codes. For each scenario, determine whether the link-edit step and go step should execute. The JCL uses COND=(8,LT) on both the link-edit and go steps.

Scenario Compile RC Should LKED Run? Should GO Run?
a) 0 ? ?
b) 4 ? ?
c) 8 ? ?
d) 12 ? ?

Solution:

The condition COND=(8,LT) means "skip this step if 8 is less than any previous step's return code" -- that is, skip if any prior RC is greater than 8.

a) Compile RC=0: 8 < 0? No. LKED runs. Assume LKED RC=0: 8 < 0? No. GO runs.

b) Compile RC=4: 8 < 4? No. LKED runs. Assume LKED RC=0: 8 < 4? No, 8 < 0? No. GO runs.

c) Compile RC=8: 8 < 8? No. LKED runs. Assume LKED RC=0: 8 < 8? No. GO runs. (RC=8 means errors, so object code may be unreliable, but JCL does not prevent execution.)

d) Compile RC=12: 8 < 12? Yes. LKED is skipped. Since LKED did not run, GO also has COND=(8,LT) which still checks compile RC: 8 < 12? Yes. GO is skipped.


Exercise 5: DD Statement Matching

A COBOL program has the following FILE-CONTROL paragraph:

       FILE-CONTROL.
           SELECT CUSTOMER-MASTER
               ASSIGN TO CUSTMAST.
           SELECT TRANSACTION-INPUT
               ASSIGN TO TRANSIN.
           SELECT REPORT-OUTPUT
               ASSIGN TO RPTFILE.
           SELECT ERROR-FILE
               ASSIGN TO ERRFILE.

Write the four DD statements needed to run this program. The customer master is an existing production VSAM KSDS. The transaction input is an existing sequential file. The report goes to the JES spool. The error file is a new sequential dataset, 80 bytes per record, blocked.

Solution:

//CUSTMAST DD  DSN=PROD.CUSTOMER.KSDS,DISP=SHR
//TRANSIN  DD  DSN=PROD.DAILY.TRANSACTIONS,DISP=SHR
//RPTFILE  DD  SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//ERRFILE  DD  DSN=PROD.DAILY.ERRORS,
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(1,1),RLSE),
//             DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
//             UNIT=SYSDA

Note: The VSAM KSDS does not need DCB parameters because its characteristics are stored in the VSAM catalog. The report file uses RECFM=FBA with LRECL=133 (132 characters plus 1 ASA carriage control character). The error file uses BLKSIZE=0 to let the system choose an optimal block size.


Exercise 6: GDG Relative Generation Numbers

A GDG base PROD.PAYROLL.HISTORY currently has generations through the absolute generation number G0045V00 (generation 45 is the most current). Answer the following:

a) What relative number refers to the current generation? b) What relative number refers to the generation created two runs ago? c) What relative number would create the next new generation? d) If a job creates (+1) in step 1 and reads (0) in step 2, does step 2 read the generation just created in step 1? Why or why not? e) How can step 2 read the generation created in step 1?

Solution:

a) (0) refers to the current generation (G0045V00).

b) (-2) refers to two generations back (G0043V00).

c) (+1) creates the next new generation (which will become G0046V00).

d) No. Relative generation numbers are resolved at job start time, not at step execution time. When the job begins, (0) resolves to G0045V00 (the existing current). The (+1) created in step 1 becomes G0046V00, but (0) in step 2 still points to the pre-job-start generation G0045V00.

e) Use a referback to the step 1 DD: DSN=*.STEP010.PAYFILE. This directly references the dataset created in step 1, regardless of GDG numbering.


Exercise 7: JCL Error Identification

Find the errors in each of the following JCL statements:

a)  //STEP-01  EXEC PGM=PAYROLL
b)  //INFILE   DD  DSN=PROD.FILE A.DATA,DISP=SHR
c)  //OUTFILE  DD  DSN=PROD.OUTPUT,DISP=NEW
d)  //BIGNAME9 DD  DSN=PROD.DATA,DISP=SHR
e)  // STEP02  EXEC PGM=REPORT
f)  //OUTFILE  DD  DSN=PROD.THIS.IS.A.VERY.LONG.DATASET.NAME.THAT.EXCEEDS,
//                DISP=(NEW,CATLG,DELETE)

Solution:

a) Invalid step name. JCL names cannot contain hyphens. Use underscores or no separator: STEP01 or STEP_01 (though underscores may not be supported on all systems; alphanumeric characters are safest).

b) Embedded space in dataset name. Dataset names cannot contain spaces. PROD.FILE A.DATA is invalid. Use PROD.FILEA.DATA or PROD.FILE.A.DATA.

c) Missing normal and abnormal disposition. DISP=NEW without the second subparameter means the dataset will be deleted when the step ends. Should be DISP=(NEW,CATLG,DELETE).

d) Name field too long. JCL names (columns 3-10) can be at most 8 characters. BIGNAME9 is 8 characters and is valid. (This was a trick -- no error.)

e) Name does not start in column 3. There is a space before STEP02, placing it in column 4. JCL names must begin in column 3.

f) Dataset name exceeds 44 characters. PROD.THIS.IS.A.VERY.LONG.DATASET.NAME.THAT.EXCEEDS is 52 characters. The maximum is 44.


Exercise 8: Procedure Parameter Overrides

Given the following procedure definition:

//RUNPGM   PROC PGMNAME=,INPDSN=,REGION=64M
//RUN      EXEC PGM=&PGMNAME,REGION=&REGION
//STEPLIB  DD  DSN=PROD.LOADLIB,DISP=SHR
//INPUT    DD  DSN=&INPDSN,DISP=SHR
//OUTPUT   DD  SYSOUT=*
//RUNPGM   PEND

Write the EXEC statement to invoke this procedure with: - Program name: PAYROLL - Input dataset: TEST.PAY.TRANS - Region size: 128M (override the default) - Additionally, override the STEPLIB to use a test load library

Solution:

//STEP01   EXEC RUNPGM,
//             PGMNAME=PAYROLL,
//             INPDSN='TEST.PAY.TRANS',
//             REGION=128M
//RUN.STEPLIB DD DSN=TEST.COBOL.LOADLIB,DISP=SHR

The symbolic parameters are overridden on the EXEC statement. The STEPLIB DD override uses the procstep.ddname format (RUN.STEPLIB) because STEPLIB is within the RUN step of the procedure. The override completely replaces the original DD statement.


Tier 2: Understand (Exercises 9-16)

Write complete JCL to compile, link-edit, and execute a COBOL program called ACCTPOST. Requirements:

  • Account number: ACCT42, department: FINANCE
  • Compiler options: SOURCE, LIST, MAP, XREF, APOST, RENT
  • The COBOL source is in DEV.COBOL.SOURCE(ACCTPOST)
  • Copybooks are in two libraries: DEV.COBOL.COPYLIB and PROD.COBOL.COPYLIB
  • The load module goes to DEV.COBOL.LOADLIB(ACCTPOST)
  • The program reads TEST.ACCOUNT.MASTER (VSAM KSDS)
  • The program reads TEST.DAILY.TRANS (sequential, FB, LRECL=150)
  • The program writes TEST.ACCOUNT.UPDATED (sequential, FB, LRECL=200, new)
  • The program writes a report to the spool
  • Skip the link step if compile RC > 8
  • Skip the go step if compile RC > 8 or link RC > 4

Solution:

//ACCTPOST JOB (ACCT42,'FINANCE'),
//             'ACCTPOST CLG',
//             CLASS=A,
//             MSGCLASS=X,
//             MSGLEVEL=(1,1),
//             NOTIFY=&SYSUID,
//             REGION=0M
//*
//*------------------------------------------------------------*
//*  STEP 1 - COMPILE                                          *
//*------------------------------------------------------------*
//COMPILE  EXEC PGM=IGYCRCTL,
//             PARM='SOURCE,LIST,MAP,XREF,APOST,RENT'
//STEPLIB  DD  DSN=IGY.V6R4M0.SIGYCOMP,DISP=SHR
//SYSIN    DD  DSN=DEV.COBOL.SOURCE(ACCTPOST),DISP=SHR
//SYSLIB   DD  DSN=DEV.COBOL.COPYLIB,DISP=SHR
//         DD  DSN=PROD.COBOL.COPYLIB,DISP=SHR
//SYSPRINT DD  SYSOUT=*
//SYSLIN   DD  DSN=&&OBJMOD,DISP=(MOD,PASS),
//             SPACE=(TRK,(10,5)),
//             DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
//SYSUT1   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT2   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT3   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT4   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT5   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT6   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT7   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//*
//*------------------------------------------------------------*
//*  STEP 2 - LINK-EDIT (skip if compile RC > 8)               *
//*------------------------------------------------------------*
//LKED     EXEC PGM=IEWL,
//             COND=(8,LT,COMPILE),
//             PARM='LIST,MAP,RENT,XREF'
//SYSLIB   DD  DSN=CEE.SCEELKED,DISP=SHR
//SYSLIN   DD  DSN=&&OBJMOD,DISP=(OLD,DELETE)
//         DD  *
  NAME ACCTPOST(R)
/*
//SYSLMOD  DD  DSN=DEV.COBOL.LOADLIB(ACCTPOST),DISP=SHR
//SYSPRINT DD  SYSOUT=*
//SYSUT1   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//*
//*------------------------------------------------------------*
//*  STEP 3 - EXECUTE (skip if compile RC > 8 or link RC > 4)  *
//*------------------------------------------------------------*
//GO       EXEC PGM=ACCTPOST,
//             COND=((8,LT,COMPILE),(4,LT,LKED)),
//             REGION=64M
//STEPLIB  DD  DSN=DEV.COBOL.LOADLIB,DISP=SHR
//ACCTMAST DD  DSN=TEST.ACCOUNT.MASTER,DISP=SHR
//TRANSIN  DD  DSN=TEST.DAILY.TRANS,DISP=SHR
//ACCTOUT  DD  DSN=TEST.ACCOUNT.UPDATED,
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(5,2),RLSE),
//             DCB=(RECFM=FB,LRECL=200,BLKSIZE=0),
//             UNIT=SYSDA
//RPTFILE  DD  SYSOUT=*
//SYSOUT   DD  SYSOUT=*
//CEEDUMP  DD  SYSOUT=*
//SYSUDUMP DD  SYSOUT=*

Exercise 10: IF/THEN/ELSE/ENDIF Logic

Rewrite the following COND-based JCL using IF/THEN/ELSE/ENDIF. Make the logic clearer and add a notification step that runs only when STEP020 fails.

//STEP010  EXEC PGM=VALIDATE
//STEP020  EXEC PGM=PROCESS,COND=(0,NE,STEP010)
//STEP030  EXEC PGM=REPORT,COND=((0,NE,STEP010),(4,LT,STEP020))
//STEP040  EXEC PGM=CLEANUP,COND=(0,NE,STEP010)

Solution:

//STEP010  EXEC PGM=VALIDATE
//*
// IF (STEP010.RC = 0) THEN
//*------------------------------------------------------------*
//*  VALIDATION PASSED - PROCEED WITH PROCESSING               *
//*------------------------------------------------------------*
//STEP020  EXEC PGM=PROCESS
//*
//   IF (STEP020.RC <= 4) THEN
//*------------------------------------------------------------*
//*  PROCESSING SUCCESSFUL - GENERATE REPORT                   *
//*------------------------------------------------------------*
//STEP030  EXEC PGM=REPORT
//   ELSE
//*------------------------------------------------------------*
//*  PROCESSING FAILED - NOTIFY OPERATIONS                     *
//*------------------------------------------------------------*
//NOTIFY   EXEC PGM=SENDMSG,
//             PARM='PROCESS STEP FAILED'
//   ENDIF
//*
//*------------------------------------------------------------*
//*  CLEANUP RUNS AFTER SUCCESSFUL VALIDATION                  *
//*------------------------------------------------------------*
//STEP040  EXEC PGM=CLEANUP
//*
// ENDIF

The IF/THEN/ELSE/ENDIF version is significantly more readable because the conditions express when steps should run, rather than the inverted COND logic that specifies when steps should be skipped.


Exercise 11: Multi-Step Banking Job

Write a complete multi-step JCL job for an end-of-day banking process. The job must:

  1. STEP010: Sort daily transactions by account number (use DFSORT)
  2. STEP020: Post sorted transactions to account master (COBOL program ACCTPOST)
  3. STEP030: Generate account statements (COBOL program STMTGEN) -- only if STEP020 returns 0 or 4
  4. STEP040: Archive processed transactions (IEBGENER copy to archive dataset) -- only if STEP020 returns 0 or 4
  5. STEP050: Send notification if any step returned > 4

Use IF/THEN/ELSE/ENDIF for conditional logic. Pass the sorted transaction file from STEP010 to STEP020 using a temporary dataset.

Solution:

//EODBANK  JOB (ACCT01,'BANKING'),
//             'EOD PROCESSING',
//             CLASS=A,
//             MSGCLASS=X,
//             MSGLEVEL=(1,1),
//             NOTIFY=&SYSUID,
//             REGION=0M,
//             TIME=60
//*
//*============================================================*
//*  END-OF-DAY BANKING BATCH PROCESSING                       *
//*============================================================*
//*
//*------------------------------------------------------------*
//*  STEP010 - SORT DAILY TRANSACTIONS BY ACCOUNT NUMBER       *
//*------------------------------------------------------------*
//STEP010  EXEC PGM=SORT,REGION=256M
//SYSOUT   DD  SYSOUT=*
//SORTIN   DD  DSN=PROD.DAILY.TRANSACTIONS,DISP=SHR
//SORTOUT  DD  DSN=&&SORTED,
//             DISP=(NEW,PASS),
//             SPACE=(CYL,(20,10)),
//             DCB=(RECFM=FB,LRECL=150,BLKSIZE=0)
//SORTWK01 DD  SPACE=(CYL,(50,20)),UNIT=SYSDA
//SORTWK02 DD  SPACE=(CYL,(50,20)),UNIT=SYSDA
//SORTWK03 DD  SPACE=(CYL,(50,20)),UNIT=SYSDA
//SYSIN    DD  *
  SORT FIELDS=(1,10,CH,A)
  OPTION EQUALS
/*
//*
// IF (STEP010.RC = 0) THEN
//*------------------------------------------------------------*
//*  STEP020 - POST TRANSACTIONS TO ACCOUNT MASTER             *
//*------------------------------------------------------------*
//STEP020  EXEC PGM=ACCTPOST,REGION=128M
//STEPLIB  DD  DSN=PROD.COBOL.LOADLIB,DISP=SHR
//TRANSIN  DD  DSN=&&SORTED,DISP=(OLD,PASS)
//ACCTMAST DD  DSN=PROD.ACCOUNT.MASTER,DISP=OLD
//ERRFILE  DD  DSN=PROD.POSTING.ERRORS,
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(1,1),RLSE),
//             DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//RPTFILE  DD  SYSOUT=*
//SYSOUT   DD  SYSOUT=*
//*
//   IF (STEP020.RC <= 4) THEN
//*------------------------------------------------------------*
//*  STEP030 - GENERATE ACCOUNT STATEMENTS                     *
//*------------------------------------------------------------*
//STEP030  EXEC PGM=STMTGEN,REGION=128M
//STEPLIB  DD  DSN=PROD.COBOL.LOADLIB,DISP=SHR
//ACCTMAST DD  DSN=PROD.ACCOUNT.MASTER,DISP=SHR
//STMTOUT  DD  DSN=PROD.DAILY.STATEMENTS,
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(50,20),RLSE),
//             DCB=(RECFM=FB,LRECL=250,BLKSIZE=0)
//RPTFILE  DD  SYSOUT=*
//*
//*------------------------------------------------------------*
//*  STEP040 - ARCHIVE PROCESSED TRANSACTIONS                  *
//*------------------------------------------------------------*
//STEP040  EXEC PGM=IEBGENER
//SYSPRINT DD  SYSOUT=*
//SYSIN    DD  DUMMY
//SYSUT1   DD  DSN=&&SORTED,DISP=(OLD,DELETE)
//SYSUT2   DD  DSN=PROD.TRANS.ARCHIVE(+1),
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(20,10),RLSE),
//             DCB=(RECFM=FB,LRECL=150,BLKSIZE=0)
//   ELSE
//*------------------------------------------------------------*
//*  STEP050 - NOTIFY ON POSTING FAILURE                       *
//*------------------------------------------------------------*
//STEP050  EXEC PGM=SENDMSG,
//             PARM='EOD POSTING FAILED - RC > 4'
//   ENDIF
//*
// ELSE
//*------------------------------------------------------------*
//*  NOTIFY ON SORT FAILURE                                    *
//*------------------------------------------------------------*
//SRTNOTFY EXEC PGM=SENDMSG,
//             PARM='EOD SORT FAILED'
// ENDIF

Exercise 12: Procedure with Symbolic Parameters

Write a cataloged procedure called COBCLG that compiles, link-edits, and executes a COBOL program. The procedure must accept the following symbolic parameters with the defaults shown:

Parameter Default Description
&SRCLIB (none, required) Source library PDS
&MEMBER (none, required) Source member name
&CPYLIB PROD.COBOL.COPYLIB Copybook library
&LOADLIB DEV.COBOL.LOADLIB Load module library
&COPTS 'SOURCE,LIST,MAP,XREF' Compiler options
&RGNSZ 64M Execution region size

Then show how to invoke the procedure to compile and run the ARPROC program from DEV.COBOL.SOURCE, using a test copybook library and 128M region.

Solution:

Procedure definition:

//COBCLG   PROC SRCLIB=,
//             MEMBER=,
//             CPYLIB=PROD.COBOL.COPYLIB,
//             LOADLIB=DEV.COBOL.LOADLIB,
//             COPTS='SOURCE,LIST,MAP,XREF',
//             RGNSZ=64M
//*
//COBOL    EXEC PGM=IGYCRCTL,
//             PARM='&COPTS,APOST,RENT'
//STEPLIB  DD  DSN=IGY.V6R4M0.SIGYCOMP,DISP=SHR
//SYSIN    DD  DSN=&SRCLIB(&MEMBER),DISP=SHR
//SYSLIB   DD  DSN=&CPYLIB,DISP=SHR
//SYSPRINT DD  SYSOUT=*
//SYSLIN   DD  DSN=&&OBJMOD,DISP=(MOD,PASS),
//             SPACE=(TRK,(10,5))
//SYSUT1   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT2   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT3   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT4   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT5   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT6   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT7   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//*
//LKED     EXEC PGM=IEWL,
//             COND=(8,LT,COBOL),
//             PARM='LIST,MAP,RENT'
//SYSLIB   DD  DSN=CEE.SCEELKED,DISP=SHR
//SYSLIN   DD  DSN=&&OBJMOD,DISP=(OLD,DELETE)
//         DD  *
  NAME &MEMBER.(R)
/*
//SYSLMOD  DD  DSN=&LOADLIB(&MEMBER),DISP=SHR
//SYSPRINT DD  SYSOUT=*
//SYSUT1   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//*
//GO       EXEC PGM=&MEMBER,
//             COND=((8,LT,COBOL),(4,LT,LKED)),
//             REGION=&RGNSZ
//STEPLIB  DD  DSN=&LOADLIB,DISP=SHR
//SYSOUT   DD  SYSOUT=*
//CEEDUMP  DD  SYSOUT=*
//COBCLG   PEND

Invocation:

//MYLIBS   JCLLIB ORDER=(DEV.JCLLIB)
//TESTAR   EXEC COBCLG,
//             SRCLIB='DEV.COBOL.SOURCE',
//             MEMBER=ARPROC,
//             CPYLIB='TEST.COBOL.COPYLIB',
//             RGNSZ=128M
//GO.ARINPUT DD DSN=TEST.AR.TRANSACTIONS,DISP=SHR
//GO.AROUTPT DD SYSOUT=*

Exercise 13: GDG Creation and Usage

Write a complete JCL job that:

  1. Defines a new GDG base DEV.LOAN.HISTORY with a limit of 12 generations, NOEMPTY, SCRATCH
  2. Creates the first generation with loan processing output (FB, LRECL=300)
  3. In a later job, references the current generation (0) as input and creates a new generation (+1)

Solution:

Job 1 -- Define GDG and create first generation:

//GDGSETUP JOB (ACCT01),'GDG SETUP',CLASS=A,
//             MSGCLASS=X,NOTIFY=&SYSUID
//*
//*------------------------------------------------------------*
//*  STEP 1 - DEFINE GDG BASE                                  *
//*------------------------------------------------------------*
//DEFGDG   EXEC PGM=IDCAMS
//SYSPRINT DD  SYSOUT=*
//SYSIN    DD  *
  DEFINE GDG -
         (NAME(DEV.LOAN.HISTORY) -
          LIMIT(12) -
          NOEMPTY -
          SCRATCH)
/*
//*
// IF (DEFGDG.RC = 0) THEN
//*------------------------------------------------------------*
//*  STEP 2 - CREATE FIRST GENERATION                          *
//*------------------------------------------------------------*
//LOANPROC EXEC PGM=LOANPOST,REGION=64M
//STEPLIB  DD  DSN=DEV.COBOL.LOADLIB,DISP=SHR
//INPUT    DD  DSN=DEV.LOAN.APPLICATIONS,DISP=SHR
//OUTPUT   DD  DSN=DEV.LOAN.HISTORY(+1),
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(5,2),RLSE),
//             DCB=(RECFM=FB,LRECL=300,BLKSIZE=0),
//             UNIT=SYSDA
//RPTFILE  DD  SYSOUT=*
// ENDIF

Job 2 -- Read current, create new generation:

//GDGUPD   JOB (ACCT01),'GDG UPDATE',CLASS=A,
//             MSGCLASS=X,NOTIFY=&SYSUID
//*
//LOANUPD  EXEC PGM=LOANUPD,REGION=64M
//STEPLIB  DD  DSN=DEV.COBOL.LOADLIB,DISP=SHR
//CURRENT  DD  DSN=DEV.LOAN.HISTORY(0),DISP=SHR
//NEWGEN   DD  DSN=DEV.LOAN.HISTORY(+1),
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(5,2),RLSE),
//             DCB=(RECFM=FB,LRECL=300,BLKSIZE=0),
//             UNIT=SYSDA
//UPDATES  DD  DSN=DEV.LOAN.UPDATES,DISP=SHR
//RPTFILE  DD  SYSOUT=*

Exercise 14: INCLUDE and JCLLIB

A team wants to standardize their JCL by placing common DD statements in INCLUDE members. Write:

a) An INCLUDE member called STDLIBS that defines the standard STEPLIB and SYSOUT DDs b) An INCLUDE member called STDCOMP that contains the standard compiler step c) A job that uses JCLLIB to locate the INCLUDE members and invokes both

Solution:

a) INCLUDE member STDLIBS:

//*------------------------------------------------------------*
//*  STANDARD LIBRARY AND OUTPUT DEFINITIONS                   *
//*------------------------------------------------------------*
//STEPLIB  DD  DSN=PROD.COBOL.LOADLIB,DISP=SHR
//         DD  DSN=PROD.UTIL.LOADLIB,DISP=SHR
//SYSOUT   DD  SYSOUT=*
//CEEDUMP  DD  SYSOUT=*
//SYSUDUMP DD  SYSOUT=*

b) INCLUDE member STDCOMP:

//*------------------------------------------------------------*
//*  STANDARD COBOL COMPILE STEP                               *
//*------------------------------------------------------------*
//COMPILE  EXEC PGM=IGYCRCTL,
//             PARM='SOURCE,LIST,MAP,XREF,APOST,RENT,OPT(1)'
//STEPLIB  DD  DSN=IGY.V6R4M0.SIGYCOMP,DISP=SHR
//SYSLIB   DD  DSN=PROD.COBOL.COPYLIB,DISP=SHR
//SYSPRINT DD  SYSOUT=*
//SYSLIN   DD  DSN=&&OBJMOD,DISP=(MOD,PASS),
//             SPACE=(TRK,(10,5))
//SYSUT1   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT2   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT3   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT4   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT5   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT6   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//SYSUT7   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA

c) Job using JCLLIB and INCLUDE:

//MYJOB    JOB (ACCT01),'INCLUDE DEMO',CLASS=A,
//             MSGCLASS=X,NOTIFY=&SYSUID
//MYLIBS   JCLLIB ORDER=(DEV.JCL.INCLUDE,PROD.JCL.INCLUDE)
//*
//*  Use standard compile step
// INCLUDE MEMBER=STDCOMP
//COMPILE.SYSIN DD DSN=DEV.COBOL.SOURCE(ARPROC),DISP=SHR
//*
//*  Link step
//LKED     EXEC PGM=IEWL,COND=(8,LT,COMPILE)
//SYSLIB   DD  DSN=CEE.SCEELKED,DISP=SHR
//SYSLIN   DD  DSN=&&OBJMOD,DISP=(OLD,DELETE)
//SYSLMOD  DD  DSN=DEV.COBOL.LOADLIB(ARPROC),DISP=SHR
//SYSPRINT DD  SYSOUT=*
//SYSUT1   DD  SPACE=(CYL,(1,1)),UNIT=SYSDA
//*
//*  Execute with standard libraries
//GO       EXEC PGM=ARPROC,COND=((8,LT,COMPILE),(4,LT,LKED))
// INCLUDE MEMBER=STDLIBS
//ARINPUT  DD  DSN=TEST.AR.DATA,DISP=SHR
//AROUTPUT DD  SYSOUT=*

Exercise 15: Dataset Utility Operations

Write JCL steps for each of the following operations:

a) Copy a PDS member PAYROLL from DEV.COBOL.SOURCE to PROD.COBOL.SOURCE using IEBCOPY b) Delete a VSAM KSDS called TEST.CUSTOMER.KSDS using IDCAMS (handle the case where it may not exist) c) Create a VSAM KSDS with a 10-byte key at offset 0, average record size 350 bytes, initial allocation for 50,000 records d) Load data from a sequential file into the new VSAM KSDS using IDCAMS REPRO

Solution:

a) IEBCOPY member copy:

//COPY     EXEC PGM=IEBCOPY
//SYSPRINT DD  SYSOUT=*
//INLIB    DD  DSN=DEV.COBOL.SOURCE,DISP=SHR
//OUTLIB   DD  DSN=PROD.COBOL.SOURCE,DISP=SHR
//SYSUT3   DD  SPACE=(CYL,(5,5)),UNIT=SYSDA
//SYSUT4   DD  SPACE=(CYL,(5,5)),UNIT=SYSDA
//SYSIN    DD  *
  COPY OUTDD=OUTLIB,INDD=INLIB
  SELECT MEMBER=PAYROLL
/*

b) IDCAMS delete with error suppression:

//DELVSAM  EXEC PGM=IDCAMS
//SYSPRINT DD  SYSOUT=*
//SYSIN    DD  *
  DELETE TEST.CUSTOMER.KSDS CLUSTER PURGE
  SET MAXCC = 0
/*

c) IDCAMS DEFINE CLUSTER:

//DEFVSAM  EXEC PGM=IDCAMS
//SYSPRINT DD  SYSOUT=*
//SYSIN    DD  *
  DEFINE CLUSTER -
         (NAME(TEST.CUSTOMER.KSDS) -
          INDEXED -
          RECORDS(50000 10000) -
          RECORDSIZE(350 350) -
          FREESPACE(20 10) -
          SHAREOPTIONS(2 3) -
          SPEED) -
         DATA -
         (NAME(TEST.CUSTOMER.KSDS.DATA) -
          CONTROLINTERVALSIZE(4096) -
          KEYS(10 0)) -
         INDEX -
         (NAME(TEST.CUSTOMER.KSDS.INDEX))
/*

d) IDCAMS REPRO to load data:

//LOADVSAM EXEC PGM=IDCAMS
//SYSPRINT DD  SYSOUT=*
//SEQFILE  DD  DSN=TEST.CUSTOMER.SEQDATA,DISP=SHR
//VSAMFILE DD  DSN=TEST.CUSTOMER.KSDS,DISP=SHR
//SYSIN    DD  *
  REPRO INFILE(SEQFILE) OUTFILE(VSAMFILE)
/*

Exercise 16: DFSORT with INCLUDE and OUTREC

Write JCL for a DFSORT step that processes a transaction file (RECFM=FB, LRECL=150) with the following requirements:

  • Include only records where the transaction code at position 45 (1 byte) is 'D' (debit) or 'C' (credit)
  • Sort by account number (positions 1-10, character, ascending) and transaction date (positions 11-18, character, descending)
  • In the output, reformat the record to include only: account number (1-10), transaction date (11-18), amount (positions 50-60), and transaction code (45)

Write both the JCL and the DFSORT control statements.

Solution:

//SORTRANS EXEC PGM=SORT,REGION=128M
//SYSOUT   DD  SYSOUT=*
//SORTIN   DD  DSN=PROD.DAILY.TRANSACTIONS,DISP=SHR
//SORTOUT  DD  DSN=PROD.TRANS.SORTED,
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(10,5),RLSE),
//             DCB=(RECFM=FB,LRECL=30,BLKSIZE=0)
//SORTWK01 DD  SPACE=(CYL,(30,15)),UNIT=SYSDA
//SORTWK02 DD  SPACE=(CYL,(30,15)),UNIT=SYSDA
//SORTWK03 DD  SPACE=(CYL,(30,15)),UNIT=SYSDA
//SYSIN    DD  *
  INCLUDE COND=(45,1,CH,EQ,C'D',OR,45,1,CH,EQ,C'C')
  SORT FIELDS=(1,10,CH,A,11,8,CH,D)
  OUTREC FIELDS=(1,10,11,8,50,11,45,1)
  OPTION EQUALS
/*

The OUTREC statement selects and reorders fields for the output record: - Positions 1-10 from input (account number) map to positions 1-10 in output - Positions 11-18 from input (transaction date) map to positions 11-18 in output - Positions 50-60 from input (amount) map to positions 19-29 in output - Position 45 from input (transaction code) maps to position 30 in output

The output LRECL is 30 bytes (10 + 8 + 11 + 1).


Tier 3: Apply (Exercises 17-24)

Exercise 17: Complete Production Job with Error Handling

Write a complete production JCL job for a bank's daily loan payment processing. The job must include:

  1. Cleanup step: Delete prior output datasets if they exist (use IDCAMS with SET MAXCC)
  2. Sort step: Sort payment transactions by loan account number
  3. Processing step: Run COBOL program LOANPAY to apply payments to loan accounts
  4. Report step: Run COBOL program LOANRPT to generate payment report
  5. Archive step: Copy processed transactions to a GDG archive
  6. Notification: Send success or failure notification

Include comprehensive conditional logic, proper DISP parameters, and restart capability (cleanup step enables restart from the beginning).


Exercise 18: DB2 Program Build JCL

Write complete JCL to build and execute a COBOL-DB2 program called CUSTINQ. The build process requires:

  1. DB2 Precompile (DSNHPC) with HOST(COBOL) and APOST options
  2. COBOL Compile (IGYCRCTL) of the precompiled source
  3. Link-edit (IEWL) with the DB2 and Language Environment runtime libraries
  4. DB2 BIND (IKJEFT01) to create a DB2 package called CUSTPKG
  5. Execute the program

Show the correct concatenation of libraries at each step and proper conditional execution between steps.


Exercise 19: JCL Debugging Exercise

The following JCL job fails to run. Find and fix all errors (there are at least 7).

//PAY JOB (ACCT1),'PAYROLL RUN'
//STEP1    EXEC PGM=PAYROLL,REGION=64M
//STEPLIB  DD DSN=PROD.LOADLIB DISP=SHR
//INFILE   DD DSN=PROD.EMPLOYEE.MASTER
//             DISP=SHR
//OUTFILE  DD DSN=PROD.PAYROLL.OUTPUT
//             DISP=(NEW,CATLG,DELETE)
//             SPACE=(CYL,(10,5),RLSE)
//RPTFILE  DD SYSOUT=*
//ERRFILE  DD DSN=PROD.PAYROLL.ERRORS,
//             DISP=(NEW,CATLG,DELETE)
//             SPACE=(CYL,(1,1),RLSE),
//             DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//

Solution:

Errors found and fixed:

  1. Line 3: Missing comma between PROD.LOADLIB and DISP=SHR. Fix: DSN=PROD.LOADLIB,DISP=SHR

  2. Lines 4-5: Missing comma at end of line 4 for continuation. The DSN and DISP are on separate lines but need a comma after the DSN value: DSN=PROD.EMPLOYEE.MASTER,

  3. Lines 6-8: Missing commas for continuation. Line 6 needs a comma after PROD.PAYROLL.OUTPUT. Line 7 needs a comma after DISP=(NEW,CATLG,DELETE). Fix:

//OUTFILE  DD DSN=PROD.PAYROLL.OUTPUT,
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(10,5),RLSE)
  1. Line 8: OUTFILE has no UNIT= parameter and no DCB for a new dataset. While not strictly an error (system-managed storage might handle it), UNIT=SYSDA should be specified.

  2. Lines 10-12: Missing comma after DISP for ERRFILE. Line 11 needs: DISP=(NEW,CATLG,DELETE),

  3. Line 12: ERRFILE has no UNIT= parameter for a new dataset.

  4. Line 13: The null statement // ends the job. If this is intentional (end of job), it is valid but should have a blank line or comment before it. If there are more steps, it will terminate the job prematurely.

Corrected JCL:

//PAY      JOB (ACCT1),'PAYROLL RUN',
//             CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//STEP1    EXEC PGM=PAYROLL,REGION=64M
//STEPLIB  DD  DSN=PROD.LOADLIB,DISP=SHR
//INFILE   DD  DSN=PROD.EMPLOYEE.MASTER,
//             DISP=SHR
//OUTFILE  DD  DSN=PROD.PAYROLL.OUTPUT,
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(10,5),RLSE),
//             DCB=(RECFM=FB,LRECL=200,BLKSIZE=0),
//             UNIT=SYSDA
//RPTFILE  DD  SYSOUT=*
//ERRFILE  DD  DSN=PROD.PAYROLL.ERRORS,
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(1,1),RLSE),
//             DCB=(RECFM=FB,LRECL=200,BLKSIZE=0),
//             UNIT=SYSDA

Exercise 20: CICS Program Build JCL

Write JCL to translate, compile, and link-edit a CICS COBOL program called CUSTMAP. The process requires:

  1. CICS translation step (DFHECP1$ with COBOL3 option)
  2. COBOL compilation of the translated source
  3. Link-edit with CICS and Language Environment libraries

The CICS program uses BMS maps, so the map compilation must be included. Show how to compile the BMS map source and include both the physical map and the symbolic map in the build process.


Exercise 21: Abend Diagnosis Exercise

A production job abends with S0C7 in step PROCESS at offset X'0001A4'. The programmer has the compiler listing. Describe the complete diagnosis procedure:

a) How do you find the failing COBOL statement from the offset? b) What does S0C7 indicate? c) What are the five most common causes of S0C7 in a COBOL program? d) What JCL changes would you make to get more diagnostic information on the next run? e) Write JCL to add a SYSUDUMP DD for a formatted dump.


Exercise 22: Multi-File Dataset Management

Write JCL for a job that manages multiple related datasets for a banking application:

  1. Delete and reallocate a VSAM KSDS for customer data
  2. Define an alternate index on the customer name field
  3. Build the alternate index path
  4. Load customer data from a sequential extract file
  5. Verify the load by printing the first 50 records using IDCAMS PRINT

Include all IDCAMS control statements and proper conditional execution between steps.


Exercise 23: Procedure Library Management

A development team has the following environment:

  • Development JCL library: DEV.JCL.PROCLIB
  • Test JCL library: TEST.JCL.PROCLIB
  • Production JCL library: PROD.JCL.PROCLIB
  • System procedure library: SYS1.PROCLIB

Write a job that: a) Uses JCLLIB to search libraries in the correct order for a development run b) Invokes a custom procedure COBTEST from the development library c) Overrides two DD statements within the procedure d) Adds a new DD statement that the procedure does not define

Explain the difference between overriding and adding DD statements in procedures.


Exercise 24: DFSORT Advanced Operations

Write JCL using ICETOOL (DFSORT's batch tool) to perform the following operations on a bank's transaction file in a single job step:

  1. Count the total number of records
  2. Produce statistics (min, max, average) on the transaction amount field (positions 50-60, packed decimal)
  3. Select only transactions over $10,000 and write them to a separate file
  4. Produce a summary report showing total amount by transaction type (position 45, 1 byte)

Tier 4: Analyze (Exercises 25-32)

Exercise 25: Job Restart Strategy Design

A critical batch job has 8 steps and processes 10 million records. The job typically takes 4 hours. Design a JCL restart strategy that handles the following scenarios:

a) The job fails in step 5. How do you restart from step 5 without rerunning steps 1-4? b) Step 3 creates a temporary dataset used by step 5. After restart, the temporary dataset is gone. How do you handle this? c) Step 2 updates a VSAM file that step 6 reads. If you restart from step 5, step 2 has already made changes. How do you ensure data consistency? d) Write the JCL modifications needed to support restart from any step.

Hint: Consider using permanent datasets instead of temporary ones, checkpoint/restart logic in COBOL programs, and cleanup/reset steps at the beginning of the job.


Exercise 26: JCL Performance Tuning

A bank's end-of-day batch job takes 6 hours. The batch window is 5 hours. Analyze the following job flow and identify at least five performance improvements:

//STEP010  EXEC PGM=SORT        (Sort trans: 45 min)
//STEP020  EXEC PGM=VALIDATE    (Validate: 30 min)
//STEP030  EXEC PGM=POSTING     (Post trans: 120 min)
//STEP040  EXEC PGM=INTEREST    (Calc interest: 60 min)
//STEP050  EXEC PGM=STATEMENTS  (Gen statements: 45 min)
//STEP060  EXEC PGM=REPORTS     (Mgmt reports: 30 min)
//STEP070  EXEC PGM=ARCHIVE     (Archive: 15 min)
//STEP080  EXEC PGM=REGEXTRACT  (Regulatory: 15 min)

Hint: Consider parallelism, step consolidation, SORT parameters, buffer allocation, and dataset placement.


Exercise 27: COND Parameter Deep Analysis

Analyze the following JCL and determine for each scenario which steps execute and which are bypassed. Show your work.

//STEP01   EXEC PGM=PGM1
//STEP02   EXEC PGM=PGM2,COND=(0,NE,STEP01)
//STEP03   EXEC PGM=PGM3,COND=((0,NE,STEP01),(4,LT,STEP02))
//STEP04   EXEC PGM=PGM4,COND=(8,LE)
//STEP05   EXEC PGM=PGM5,COND=(4,LT)
Scenario STEP01 RC STEP02 RC STEP03 RC Steps that execute
A 0 0 0 ?
B 4 0 0 ?
C 0 8 0 ?
D 0 4 12 ?
E 12 - - ?

Exercise 28: Symbolic Parameter Design

Design a set of symbolic parameters for a flexible JCL procedure that supports multiple environments (development, test, QA, production). The procedure should automatically adjust:

  • Dataset high-level qualifier (DEV, TEST, QA, PROD)
  • Load library (different for each environment)
  • Region size (smaller for dev, larger for production)
  • Time limit (shorter for dev, longer for production)
  • SYSOUT class
  • Compiler optimization level (OPT(0) for dev/test, OPT(2) for production)

Write the procedure with all symbolic parameters, default values for the development environment, and show invocations for each of the four environments.


Exercise 29: VSAM Reorganization Job

A production VSAM KSDS has become fragmented after months of inserts and deletes. CI splits have degraded read performance by 40%. Design a complete JCL job to reorganize the VSAM file with zero data loss. The job must:

  1. Back up the VSAM file to a sequential backup
  2. Verify the backup record count matches the VSAM record count
  3. Delete and redefine the VSAM cluster with optimized FREESPACE
  4. Reload the data from the backup
  5. Rebuild any alternate indexes
  6. Verify the reloaded file has the correct record count
  7. Handle failures at any step without data loss

Hint: Use IDCAMS REPRO for backup/reload, LISTCAT for record counts, and careful conditional logic.


Exercise 30: Cross-System Data Transfer

Design JCL for transferring a daily transaction extract from a mainframe to a distributed system. The process must:

  1. Extract data from a VSAM file using a COBOL program
  2. Sort the extract by region code
  3. Convert the EBCDIC extract to ASCII using ICONV or a COBOL program
  4. FTP the file to a remote server (using the TSO FTP batch interface)
  5. Verify the transfer was successful
  6. Write an audit record

Address character encoding issues, file format differences (RECFM=FB vs. line-delimited text), and error handling for network failures.


Exercise 31: Parallel Job Stream Design

A bank processes transactions from five channels (ATM, Teller, Online, Mobile, ACH). Design a parallel job stream that:

  1. Sorts each channel's transactions independently (5 parallel sort jobs)
  2. Waits for all sorts to complete
  3. Merges the five sorted files
  4. Processes the merged file

Draw the dependency graph. Write the JCL for the parallel sort jobs and explain how a job scheduler (TWS/CA-7/Control-M) would coordinate the parallel execution and synchronization.


Exercise 32: Disaster Recovery JCL

Design JCL for a disaster recovery scenario. The production dataset PROD.ACCOUNT.MASTER has been corrupted. The last good backup is 3 days old. You have:

  • The backup from 3 days ago: PROD.ACCOUNT.MASTER.BACKUP.G0045V00
  • Three days of transaction GDG generations: PROD.DAILY.TRANS(-2), PROD.DAILY.TRANS(-1), PROD.DAILY.TRANS(0)

Write a recovery job that: 1. Restores the backup to a new VSAM KSDS 2. Applies the three days of transactions in chronological order 3. Verifies the recovery by comparing record counts and control totals 4. Renames the recovered file to replace the corrupted production file


Tier 5: Create (Exercises 33-38)

Exercise 33: Complete Development-to-Production Pipeline

Design a comprehensive JCL-based deployment pipeline for a banking application. The pipeline must include:

  1. Compile all changed COBOL programs
  2. Link-edit with proper library concatenation
  3. Bind DB2 packages for changed DB2 programs
  4. Run unit tests with test data
  5. Compare test results to expected results
  6. Promote load modules from test to QA to production libraries
  7. Send deployment notifications

Write the JCL for each stage. Use procedures with symbolic parameters to support multiple environments. Include a rollback procedure that restores the previous version.


Exercise 34: JCL Generation Framework

Design a COBOL program that reads a control file and generates JCL dynamically. The control file specifies:

  • Program name to execute
  • Input dataset names
  • Output dataset names and characteristics
  • Conditional execution rules
  • Notification recipients

The generated JCL must be syntactically correct and include standard headers, error handling, and notification steps. Write the COBOL program that reads the control file and writes the JCL to an output dataset. Show at least three sample control file entries and the JCL they produce.

Hint: The COBOL program writes 80-byte records in JCL format, starting with // in positions 1-2.


Exercise 35: Multi-Entity Financial Consolidation

Design complete JCL for a monthly financial consolidation process for a corporation with 5 subsidiaries. Each subsidiary has its own general ledger dataset. The process must:

  1. Extract GL data from each subsidiary's VSAM file (5 parallel extracts)
  2. Validate each extract (check control totals, balancing debits/credits)
  3. Sort each extract by account code
  4. Merge all 5 sorted extracts into a consolidated GL
  5. Generate a consolidated trial balance report
  6. Generate intercompany elimination entries
  7. Produce the final consolidated financial statements
  8. Archive all inputs and outputs to GDG generations

Write the complete JCL with procedures for reusable steps, symbolic parameters for subsidiary-specific values, and comprehensive error handling.


Exercise 36: Automated Testing JCL Framework

Design a JCL-based automated testing framework that:

  1. Extracts test data from a test case library (PDS with one member per test case)
  2. Runs the program under test with each test case
  3. Compares actual output to expected output (stored in another PDS)
  4. Produces a test results summary
  5. Sets a return code of 0 if all tests pass, 4 if any test has a warning, and 8 if any test fails

Write the JCL framework using a procedure that is invoked once per test case. Use IEBCOMPR or a custom comparison program for output comparison.


Exercise 37: Batch Scheduling Documentation

Design a complete batch schedule for a mid-size bank's end-of-day processing. Document:

  1. A job dependency diagram showing all jobs and their dependencies
  2. The JCL for the five most critical jobs
  3. The scheduler definitions (using pseudocode for the scheduler syntax) showing: - Job dependencies - Time windows - Resource requirements - Restart instructions for each job
  4. A runbook entry for operations staff describing what to do if each critical job fails

Exercise 38: JCL Standards and Governance

Design a complete JCL standards document for a banking development team. Include:

  1. Naming conventions for jobs, steps, DD names, and datasets
  2. Required parameters for JOB, EXEC, and DD statements
  3. Templates for common job types (compile-link-go, batch processing, utility operations)
  4. Error handling standards (required conditional logic, notification requirements)
  5. Security standards (RACF resource names, authorization requirements)
  6. Performance standards (REGION, SORT parameters, buffer specifications)
  7. A JCL review checklist for code reviews

Write the standards document as a series of rules with examples, and write a sample "golden" JCL job that demonstrates all standards.