JCL PROCEDURE (PROC)

JCL Procedures are reusable code to perform the same function like language compiler and linkage editor programs in different JCLs.. There are 2 types of procedures which are INSTREAM and Cataloged PROCEDURES.

What is PROC (PROCEDURE) in JCL and insights?:

  • Reusable code to perform the same function like language compiler and linkage editor programs.
  • There are 2 types of procedures which are INSTREAM and Cataloged PROCEDURES.
  • If a PROCEDURE is placed in the same JOB as the PROC invocation then it is called INSTREAM PROCEDURE.
  • INSTREAM PROCEDURE should start with a PROC statement and end with a PEND statement.
  • CATALOGUED PROCEDURE should start with a PROC statement and PEND is optional.
  • Can code upto 15 instream procs in one JCL.
  • Parameters can be passed to procedures and can specify default parameters for use.
  • Begin with a PROC statement or an EXEC statement.
  • EXEC, DD and comment statements can be placed in a procedure.
  • DD statements defining private libraries to be used throughout the job (JOBLIB) not to be coded in instream or catalogued procedures.
  • DD statements defining instream datasets should not be coded in procedures.
  • Delimiter and Null statements should not be used in procedures.
  • Can assign actual values to the symbolic parameters in the procedure.
  • Overriding the existing parameters of the EXEC and DD statements in the procedure.
  • Nullifying the existing parameters of the EXEC and DD statements in the procedure.
  • Adding new DD statements to the procedure.
  • Adding new parameters to the EXEC and DD statements in the procedure.
  • Users invoke a Proc by coding ‘EXEC Proc-Name or PROC=Proc-Name’

Use of PROC:

  • Repeating the same code is eliminated with reusable capability.
  • Eliminates coding errors.
  • Reduces redundancy.

How to write JCL PROCEDURE (PROC):

INSTREAM PROCEDURE:

Lets convert an existing JCL into an INSTREAM PROCEDURE and learn how to code a PROC: 

This is an example JCL which Sorts a dataset. We will converr this into an INSTREAM PROC step by step.


//PROGPUBA JOB NOTIFY=PROGPUB
//STEP010 EXEC PGM=SORT
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=
//SORTOUT DD DSN=
//SYSIN DD *
  SORT FIELDS=(1,5,CH,A)
/*
//

STEP 1:

Separate the JOB statement from the remaining JCL statements, with a PROC operation giving the PROC a name. 

In this step we have added PROC marking the beginning of PROCEDURE and PEND statement which marks the end of PROCEDURE.

A name is required on a PROC statement in an in-stream procedure. Some points to consider for name parameters are: 

  • Name must be unique within the job when coded in instream procedures. 
  • Name must contain only alphanumeric or national ($,#,@) characters. 
  • First character should not be numeric.
//PROGPUBA JOB NOTIFY=PROGPUB
//SORTPROC PROC
//STEP010 EXEC PGM=SORT
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=
//SORTOUT DD DSN=
//SYSIN DD *
  SORT FIELDS=(1,5,CH,A)
/*
//         PEND
//

STEP 2:

Remove any control statements from INSTREAM PROC and put it into a member of PDS member. Change the SYSIN to refer to the PDS member.

//PROGPUBA JOB NOTIFY=PROGPUB
//SORTPROC PROC
//STEP010 EXEC PGM=SORT
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=
//SORTOUT DD DSN=
//SYSIN DD DSN=,
//         PEND
//

STEP 3:

Replace the parameter-values with SYMBOLIC parameters (&) which act as a place holder for the actual values. A=‘ * ’ is default values for the symbolic parameters, on the PROC statement as shown in the example.

//PROGPUBA JOB NOTIFY=PROGPUB
//SORTPROC PROC A=‘ * ’
//STEP010 EXEC PGM=SORT
//SYSPRINT DD SYSOUT=&A
//SYSOUT DD SYSOUT=&A
//SORTIN DD DSN=&INPUT
//SORTOUT DD DSN=&OUTPUT
//SYSIN DD DSN=&PDS(Mem1),DISP=SHR
//         PEND
//

Now we have created the INSTREAM PROCEDURE. Inorder to execute this instream PROC  add a step in the JCL.


//PROGPUBA JOB NOTIFY=PROGPUB
//SORTPROC PROC A=‘ * ’
//STEP010 EXEC PGM=SORT
//SYSPRINT DD SYSOUT=&A
//SYSOUT DD SYSOUT=&A
//SORTIN DD DSN=&INPUT
//SORTOUT DD DSN=&OUTPUT
//SYSIN DD DSN=&PDS(Mem1),DISP=SHR
//         PEND
//STEP010 EXEC PROC=SORTPROC,
//             INPUT=‘INPUT DATASET NAME’,
//             OUTPUT=‘INPUT DATASET NAME’,
//             PDS(Member)=‘PDS MEMBER DATASET NAME’

Cataloged PROC:

The library containing cataloged procedures is a partitioned data set (PDS) or a partitioned data set extended (PDSE). The system procedure library is SYS1.PROCLIB.

Cataloged PROC is almost same as INSTREAM proc. The only changes we need to do are:

  • Remove the JOB Statement.
  • Remove the PEND Statement.
  • Remove the step010.

//SORTPROC PROC A=‘ * ’
//STEP010 EXEC PGM=SORT
//SYSPRINT DD SYSOUT=&A
//SYSOUT DD SYSOUT=&A
//SORTIN DD DSN=&INPUT
//SORTOUT DD DSN=&OUTPUT
//SYSIN DD DSN=&PDS(Mem1),DISP=SHR

Save this JCL in a PDS member to use it as a catalogued PROC. To invoke the catalogued PROC, use the JCL


//PROGPUBA JOB NOTIFY=PROGPUB
//           JCLLIB ORDER=
//STEP010 EXEC PROC=SORTPROC,
//             INPUT=‘INPUT DATASET NAME’,
//             OUTPUT=‘INPUT DATASET NAME’,
//             PDS(Member)=‘PDS MEMBER DATASET NAME’

Example JCL using PROC:

Overriding the parameters of the Exec and DD. Overriding Proc’s Stepname.DDname


//PROGPUBA JOB NOTIFY=PROGPUB
//           JCLLIB ORDER=
//STEP010 EXEC PROC=SORTPROC,
//             INPUT=‘INPUT DATASET NAME’,
//             OUTPUT=‘INPUT DATASET NAME’,
//             PDS(Member)=‘PDS MEMBER DATASET NAME’
//PSTEP010.SYSIN DD *
  SORT FIELDS=(1,5,CH,A)
/*

Nullifying the parameters of the Exec and DD: 

To nullify code just an equal (=) sign after the parameter


//PROGPUBA JOB NOTIFY=PROGPUB
//           JCLLIB ORDER=
//STEP010 EXEC PROC=SORTPROC,
//             INPUT=‘INPUT DATASET NAME’,
//             OUTPUT=‘INPUT DATASET NAME’,
//             PDS(Member)=‘PDS MEMBER DATASET NAME’
//PSTEP010.SYSOUT DD SYSOUT=
//

Adding new parameters to the EXEC and DD:


//PROGPUBA JOB NOTIFY=PROGPUB
//           JCLLIB ORDER=
//STEP010 EXEC PROC=SORTPROC,
//             INPUT=‘INPUT DATASET NAME’,
//             OUTPUT=‘INPUT DATASET NAME’,
//             PDS(Member)=‘PDS MEMBER DATASET NAME’,
//            Time.PSTEP010=(,5)
//PSTEP010.SYSOUT DD SYSOUT=
//

Instream PROC to create multiple PS files:


   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 EDIT       PROGPUB.AA.SOURCE(PRC) - 01.07                  Columns 00001 00072 
 Command ===>                                                  Scroll ===> PAGE 
 ****** ***************************** Top of Data ******************************
 000010 //PROGPUBA JOB NOTIFY=PROGPUB                                             
 000100 //P2 PROC                                                               
 000200 //S1 EXEC PGM=IEFBR14                                                   
 000300 //OUT DD DSN=&DS..&NA..&ME,DISP=(NEW,CATLG,DELETE),                     
 000400 //        SPACE=(TRK,(5,5),RLSE),                        
 000410 //        DCB=(RECFM=FB,LRECL=80,                                       
 000500 //        BLKSIZE=800,DSORG=PS),UNIT=SYSDA                              
 000600 //    PEND                                                              
 000700 //    SET DS=PROGPUB,NA=AA,ME=SS2                                       
 000800 //S2 EXEC P2                                                            
 000810 // SET DS=PROGPUB,NA=AA,ME=SS3                                          
 000900 //S3 EXEC P2                                                            
 000910 // SET DS=PROGPUB,NA=AA,ME=SS4                                          
 001000 //S4 EXEC P2                                                            
 001100 //                                                                      
 ****** **************************** Bottom of Data ****************************

Nested Instream PROC example:


   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
  EDIT       PROGPUB.AA.SOURCE(NESPROC) - 01.04             Columns 00001 00072 
  ****** ***************************** Top of Data ******************************
 000001 //PROGPUBA JOB NOTIFY=PROGPUB                                           
 000002 //P2 PROC                                                               
 000003 //S1 EXEC PGM=PROG1                                                      
 000004 //STEPLIB DD DSN=PROGPUB.AA.LOAD,DISP=SHR                              
 000005 //SYSIN DD DUMMY                                                        
 000006 // PEND                                                                 
 000007 //P1 PROC                                                               
 000008 //S2 EXEC PGM=PROG1                                                      
 000009 //STEPLIB DD DSN=PROGPUB.AA.LOAD,DISP=SHR                              
 000010 //S4 EXEC P2                                                            
 000011 //SYSIN DD DSN=PROGPUB.AA.PRG,DISP=SHR                                 
 000012 // PEND                                                                 
 000013 //S3 EXEC P1                                                            
 000014 //SYSIN DD *                                                            
 000015 TEST                                                                  
 000016 /*                                                                      
 000017 // 

Cataloged PROC example:


  File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 EDIT       PROGPUB.AA.SOURCE1(PROC1) - 01.04                 Columns 00001 00072 
 Command ===>                                                  Scroll ===> PAGE 
 ****** ***************************** Top of Data ******************************
 000001 //PROC1 PROC                                                              
 000002 //S2 EXEC PGM=PROG1                                                     
 000003 //STEPLIB DD DSN=PROGPUB.AA.LOAD,DISP=SHR                               
 000004 //SYSIN DD DUMMY                                                        
 000005 //                                                                      
 ****** **************************** Bottom of Data **************************** 

JCL which executes the cataloged PROC from example mentioned above


  File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
 EDIT       PROGPUB.AA.SOURCE(PROCJCL) - 01.05               Columns 00001 00072 
 Command ===>                                                  Scroll ===> PAGE 
 ****** ***************************** Top of Data ******************************
 000001 //PROGPUBA JOB NOTIFY=PROGPUB                                             
 000002 //JOBLIB DD DSN=PROGPUB.AA.LOAD,DISP=SHR                                
 000003 //JL1 JCLLIB ORDER=PROGPUB.AA.SOURCE                                   
 000004 //S1 EXEC PROC1                                                           
 000005 //SYSOUT DD SYSOUT=*                                                    
 000006 //S2.SYSIN DD *                                                         
 000007 TEST                                                                      
 000008 /*                                                                      
 000009 //                                                                      
 ****** **************************** Bottom of Data ****************************

Example of nested cataloged PROC

This is PROC1 which calls another cataloged PROC in step S3


    File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 -------------------------------------------------------------------------------
  EDIT       PROGPUB.AA.SOURCE(PROC1) - 01.25                Columns 00001 00072 
  ****** ***************************** Top of Data ******************************
 000001 //PROC1 PROC                                                             
 000002 //S2 EXEC PGM=PROG1                                                      
 000003 //STEPLIB DD DSN=PROGPUB.AA.LOAD,DISP=SHR                              
 000004 //S3 EXEC PROC2                                                          
 000005 //S4.SYSIN DD DSN=PROGPUB.AA.DT,DISP=SHR                              
 ****** **************************** Bottom of Data ****************************

This is cataloged PROC2


File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
-------------------------------------------------------------------------------
EDIT       PROGPUB.AA.SOURCE(PROC2) - 01.08                Columns 00001 00072 
 ****** ***************************** Top of Data ******************************
000001 //PROC2 PROC                                                             
000002 //S4 EXEC PGM=PROG2                                                      
000003 //STEPLIB DD DSN=PROGPUB.AA.LOAD,DISP=SHR                              
000004 //SYSIN DD DUMMY                                                        
****** **************************** Bottom of Data ****************************

JCL executing the nested cataloged PROC


File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
-------------------------------------------------------------------------------
 EDIT       PROGPUB.AA.SOURCE(NSTJCL) - 01.24            Columns 00001 00072 
  ****** ***************************** Top of Data ******************************
 000001 //PROGPUBA JOB NOTIFY=PROGPUB                                           
 000002 //J2 JCLLIB ORDER=PROGPUB.AA.SOURCE                                    
 000003 //S1 EXEC PROC1                                                          
 000004 //SYSOUT DD SYSOUT=*                                                    
 000005 //S2.SYSIN DD *                                                         
 000006 TEST                                                                   
 000007 /*                                                                      
 000008 //                                                                      
 ****** **************************** Bottom of Data ****************************

Quick Notes on PROCEDURES:

  • A Job can contain 15 instream procedures.
  • An Instream procedure can call a Cataloged procedure.
  • A Cataloged procedure cannot call an Instream procedure.
  • A Cataloged procedure can call a Cataloged procedure.
  • There can exist a maximum of 15 nested ‘PROC statements’ – PROC operation. If each procedure resides in 15 different PDS, then the JCLLIB ORDER must identify those PDS to the OS.
  • Restart a PROC - Syntax .
  • Forward reference – Syntax - //DDName DD DDName=‘fwd’. Then use ‘fwd’ in the name field on any subsequent DD statement.
  • In the invoking JCL of PROCs, overriding statements must come before add-on statements. Override DD statements in the order of their occurrence within the PROC.
  • To override a parameter on all the steps in a PROC with the same value, call the PROC and code the parameter=its value.
  • You can add-on and override DD parameters only one level down from the invoking step.
  • If the called PROC is not found in the private libraries of the JCLLIB order statement, then the OS searches the system library even though not coded in the JCLLIB statement.
  • To override only certain concatenated datasets in a PROC, in the calling JCL, code just ‘DSN’ for those datasets which need not be overridden.
  • If you are modifying a cataloged procedure, do not run any jobs that use the procedure during modification.