Creating reusable JCL components for standardized batch processing
Cataloged procedures are pre-written, reusable collections of JCL statements stored in a system library. They serve as templates for common processing tasks, allowing multiple jobs to use the same standardized JCL without having to duplicate the code in each job.
Key benefits of cataloged procedures include:
Stored permanently in a procedure library and available to all jobs
Defined within a job stream and only available to that job
While both types of procedures serve the same purpose and follow the same syntax rules, this tutorial focuses primarily on cataloged procedures that are stored in procedure libraries.
Cataloged procedures are stored in specialized libraries that the system searches when a procedure is referenced in a job. Common procedure libraries include:
The system searches these libraries in a predefined order when looking for a procedure. You can specify additional procedure libraries for a specific job using the JCLLIB statement:
12//MYJOB JOB (ACCT),'MY JOB',CLASS=A // JCLLIB ORDER=(USER.PROCLIB,DEPT.PROCLIB)
The JCLLIB statement must appear after the JOB statement but before any EXEC statements that reference procedures. The system searches the libraries in the order specified.
A cataloged procedure consists of JCL statements that define one or more job steps. These statements are stored as a member in a procedure library.
123456789101112131415161718192021//MYPROC PROC P1='DEFAULT1',P2='DEFAULT2' //*-------------------------------------------------- //* This procedure does something important //*-------------------------------------------------- //STEP1 EXEC PGM=PROG1,PARM='&P1' //STEPLIB DD DSN=MY.LOADLIB,DISP=SHR //INPUT DD DSN=MY.INPUT.FILE,DISP=SHR //OUTPUT DD DSN=MY.&P2..FILE, // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(10,5)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=27920) //SYSOUT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //SYSIN DD DUMMY //*-------------------------------------------------- //STEP2 EXEC PGM=PROG2,COND=(0,NE,STEP1) //INPUT DD DSN=MY.&P2..FILE,DISP=SHR //OUTPUT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //*-------------------------------------------------- // PEND
To execute a cataloged procedure, use the EXEC statement with the procedure name:
123456//MYJOB JOB (ACCT),'MY JOB',CLASS=A //*-------------------------------------------------- //* Execute the cataloged procedure MYPROC //*-------------------------------------------------- //STEP01 EXEC MYPROC //
You can override the default values of symbolic parameters when executing a procedure:
123//MYJOB JOB (ACCT),'MY JOB',CLASS=A //STEP01 EXEC MYPROC,P1='CUSTOM1',P2='CUSTOM2' //
This will replace the default parameter values in the procedure with the specified custom values.
When executing a procedure, you can override or add to the statements within it. This allows for customization while still leveraging the standardized procedure.
To override a DD statement in a procedure, include a DD statement with the qualified name stepname.ddname
:
12345//MYJOB JOB (ACCT),'MY JOB',CLASS=A //STEP01 EXEC MYPROC //STEP1.INPUT DD DSN=MY.CUSTOM.INPUT,DISP=SHR //STEP2.OUTPUT DD SYSOUT=A,DEST=REMOTE1 //
Important: You must use the step name as defined in the procedure, not the name of the EXEC statement in your job that calls the procedure.
You can add new DD statements to a procedure step using the same stepname.ddname
syntax:
1234//MYJOB JOB (ACCT),'MY JOB',CLASS=A //STEP01 EXEC MYPROC //STEP1.EXTRA DD DSN=MY.EXTRA.FILE,DISP=SHR //
You can override parameters on the EXEC statement in a procedure:
123//MYJOB JOB (ACCT),'MY JOB',CLASS=A //STEP01 EXEC MYPROC,REGION.STEP1=8M,TIME.STEP2=10 //
In this example, we override the REGION parameter for STEP1 and the TIME parameter for STEP2.
Let's look at a more comprehensive example:
1234567891011121314151617181920212223242526272829303132333435//DBLOAD PROC ENV='TEST',LOADLIB='SYS1.DB2.LOADLIB' //*-------------------------------------------------- //* Database Load Procedure //* Parameters: //* ENV - Environment (TEST/PROD) //* LOADLIB - Load library for DB2 programs //*-------------------------------------------------- //UNLOAD EXEC PGM=DSNUTILB,REGION=4M //STEPLIB DD DSN=&LOADLIB,DISP=SHR //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //DATASET DD DSN=&ENV..DATA.EXTRACT,DISP=SHR //SYSIN DD * UNLOAD TABLESPACE DSN8D81A.DSN8S81E /* //*-------------------------------------------------- //SORT EXEC PGM=SORT,COND=(4,LT,UNLOAD) //SORTIN DD DSN=&ENV..DATA.EXTRACT,DISP=SHR //SORTOUT DD DSN=&ENV..DATA.SORTED, // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(50,25),RLSE) //SYSIN DD * SORT FIELDS=(1,10,CH,A) /* //SYSOUT DD SYSOUT=* //*-------------------------------------------------- //LOAD EXEC PGM=DSNUTILB,COND=(4,LT,SORT) //STEPLIB DD DSN=&LOADLIB,DISP=SHR //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //DATASET DD DSN=&ENV..DATA.SORTED,DISP=SHR //SYSIN DD * LOAD TABLESPACE DSN8D81A.DSN8S81F /* // PEND
12345678910111213141516//PRODLOAD JOB (ACCT),'DB LOAD',CLASS=A //*-------------------------------------------------- //* Production database load with overrides //*-------------------------------------------------- //LOADJOB EXEC DBLOAD,ENV='PROD', // REGION.LOAD=8M //* Override the standard extract dataset //UNLOAD.DATASET DD DSN=PROD.SPECIAL.EXTRACT,DISP=SHR //* Add a report DD to the LOAD step //LOAD.REPORT DD SYSOUT=A //* Override the SYSIN for the LOAD step //LOAD.SYSIN DD * LOAD TABLESPACE PRODDB.CUSTDATA REPLACE LOG NO /*
In this example, we're:
A procedure can execute another procedure, creating a hierarchy of nested procedures. This allows for modular construction of complex job streams.
12345678910//MASTERP PROC ENV='TEST' //*-------------------------------------------------- //* Master procedure that calls other procedures //*-------------------------------------------------- //EXTRACT EXEC EXTRACT,ENV=&ENV //VALIDATE EXEC VALIDATE,ENV=&ENV, // COND=(0,NE,EXTRACT.EXTR) //REPORT EXEC REPORT,ENV=&ENV, // COND=(0,NE,VALIDATE.CHECK) // PEND
Most systems limit procedure nesting to 15 levels. Careful design is needed for deeply nested procedures to ensure maintainability.
When using nested procedures, parameter passing flows down through the levels. You can set parameters at the top level that affect all nested procedure calls.
Include clear comments explaining the procedure's purpose, parameters, requirements, and usage examples.
Provide meaningful default values that work in common scenarios, making the procedure easier to use.
Include appropriate COND parameters to handle errors and provide useful return codes.
Use consistent, descriptive names for procedures, steps, and parameters that follow organizational standards.
Maintain version control for procedures and document changes to ensure traceability.
Design procedures to be modular and focused on specific tasks to maximize reusability.
Create a cataloged procedure that provides a standardized way to process data files. The procedure should:
Then, create a job that calls this procedure with various overrides to demonstrate its flexibility.
Consider how you would:
Try writing the JCL yourself, then compare with a sample solution in a future lesson.
1. What is the primary purpose of cataloged procedures in JCL?
2. Where are cataloged procedures typically stored?
3. Which statement marks the end of a procedure definition?
4. How do you override a DD statement in a procedure?
5. What happens if symbolic parameters in a procedure are not given values when the procedure is called?