JCL Variables

Purpose

JCL Variables provide a way to create dynamic, reusable JCL by allowing runtime substitution of values. Unlike symbolic parameters that are limited to procedures, JCL variables can be used across the entire job and even passed between jobs. They enable more flexible and maintainable JCL by centralizing values and supporting arithmetic and string operations.

Key Benefit:

JCL Variables allow for dynamic value substitution throughout jobs, enabling parameterization and custom logic that traditional symbolic parameters cannot provide, particularly when working with system information, dates, and calculated values.

JCL Variables vs. Symbolic Parameters

FeatureJCL VariablesSymbolic Parameters
ScopeJob-wide and can be exported to other jobsLimited to the procedure in which they're defined
DefinitionSET statement anywhere in JCLPROC statement or override on EXEC statement
OperationsSupport arithmetic and string operationsSimple substitution only
System valuesCan access system symbols and built-in functionsCannot access system information

Basic Syntax

Defining Variables

jcl
1
2
3
// SET var=value // SET DATASET='MY.DATA.SET' // SET COUNT=10

Using Variables

jcl
1
2
3
//STEP1 EXEC PGM=MYPROG //DD1 DD DSN=&DATASET,DISP=SHR //DD2 DD SPACE=(TRK,(&COUNT,5))

Variable Naming Rules

  • Names can be 1-8 characters long
  • Must start with an alphabetic character (A-Z) or national character (@, #, $)
  • Remaining characters can be alphanumeric (A-Z, 0-9) or national characters
  • Cannot contain special characters or spaces
  • Case-insensitive (abc is the same as ABC)

Operations with JCL Variables

Arithmetic Operations

jcl
1
2
3
4
5
6
7
// SET A=5 // SET B=10 // SET C=&A+&B /* C = 15 */ // SET D=&C*2 /* D = 30 */ // SET E=(&A+&B)*2 /* E = 30 */ // SET F=&C/&A /* F = 3 */ // SET G=&C-&B /* G = 5 */

String Concatenation

jcl
1
2
3
4
// SET PREFIX='MY.DATA' // SET SUFFIX='FILE' // SET FULLNAME='&PREFIX..&SUFFIX' /* FULLNAME = 'MY.DATA.FILE' */ // SET JOBTXT='JOB &JOBNAME RUNNING' /* Uses system variable */

Note the double period (..) when concatenating strings - the first period is treated as a concatenation point, the second as a literal period.

Substring Operations

jcl
1
2
3
4
// SET FULLDATE='20230712' // SET YEAR=SUBSTR(&FULLDATE,1,4) /* YEAR = '2023' */ // SET MONTH=SUBSTR(&FULLDATE,5,2) /* MONTH = '07' */ // SET DAY=SUBSTR(&FULLDATE,7,2) /* DAY = '12' */

System Symbols and Functions

Symbol/FunctionDescriptionExample
&SYSUIDUser ID submitting the jobSET OWNER=&SYSUID
&SYSDATECurrent date (yyyymmdd format)SET TODAY=&SYSDATE
&SYSTIMECurrent time (hhmmss format)SET NOW=&SYSTIME
&SYSNAMESystem nameSET SYSID=&SYSNAME
&SYSPLEXSysplex nameSET PLEX=&SYSPLEX
&JOBNAMEName of the current jobSET JOB=&JOBNAME
SUBSTR()Extract substringSET YR=SUBSTR(&SYSDATE,1,4)
LENGTH()Get string lengthSET LEN=LENGTH(&NAME)
INDEX()Find position of substringSET POS=INDEX(&TEXT,'ABC')

Usage Examples

Date-Based Processing

jcl
1
2
3
4
5
6
7
8
9
10
11
12
//DATEJOB JOB (ACCT#),'ADMIN',CLASS=A // SET TODAY=&SYSDATE // SET YEAR=SUBSTR(&TODAY,1,4) // SET MONTH=SUBSTR(&TODAY,5,2) // SET DAY=SUBSTR(&TODAY,7,2) // SET YESTERDAY=&TODAY-1 //* //STEP1 EXEC PGM=REPORT //INFILE DD DSN=DATA.FILE.&YEAR&MONTH&DAY,DISP=SHR //PREVFILE DD DSN=DATA.FILE.&YESTERDAY,DISP=SHR //OUTFILE DD DSN=REPORT.&YEAR&MONTH&DAY,DISP=(NEW,CATLG), // SPACE=(CYL,(5,2)),UNIT=SYSDA

This job uses system date information to dynamically build dataset names.

Conditional Logic with Variables

jcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//CONDVAR JOB (ACCT#),'ADMIN',CLASS=A // SET ENV='PROD' // SET MAXRC=4 //* // IF &ENV = 'PROD' THEN // SET SYSID='P' // SET DATASET='PROD.MASTER.FILE' // ELSE // SET SYSID='T' // SET DATASET='TEST.MASTER.FILE' // ENDIF //* //STEP1 EXEC PGM=UPDATE //MASTER DD DSN=&DATASET,DISP=SHR //* // IF STEP1.RC > &MAXRC THEN //NOTIFY EXEC PGM=SENDMAIL // ENDIF

This example shows how to use variables with conditional logic for environment-specific processing.

Dynamic Allocation Sizes

jcl
1
2
3
4
5
6
7
8
//SIZEVAR JOB (ACCT#),'ADMIN',CLASS=A // SET FILESIZE=100 // SET PRIMARY=&FILESIZE/10 // SET SECONDARY=&PRIMARY/2 //* //STEP1 EXEC PGM=GENCOPY //OUTPUT DD DSN=MY.OUTPUT.FILE,DISP=(NEW,CATLG), // SPACE=(TRK,(&PRIMARY,&SECONDARY))

This job calculates space allocation dynamically based on a file size variable.

Building Complex Strings

jcl
1
2
3
4
5
6
7
8
9
10
11
//STRVAR JOB (ACCT#),'ADMIN',CLASS=A // SET PREFIX='DATA' // SET ENV='PROD' // SET SYSID='SYS1' // SET SEQ=101 //* // SET DSNAME='&PREFIX..&ENV..&SYSID..D&SYSDATE..S&SEQ' //* //STEP1 EXEC PGM=PROCESS //OUTPUT DD DSN=&DSNAME,DISP=(NEW,CATLG), // SPACE=(CYL,(10,5)),UNIT=SYSDA

This example builds a complex dataset name by concatenating multiple variables and literals.

Variable Scope and Context

Local vs. Global Variables

jcl
1
2
3
4
5
6
7
8
9
10
//VARSCOPE JOB (ACCT#),'ADMIN',CLASS=A // SET GLOBAL=100 /* Global variable */ //* //STEP1 EXEC PGM=PROGRAM1 //* // SET LOCAL=200 /* Local to this context */ //STEP2 EXEC PGM=PROGRAM2 //* // SET GLOBAL=300 /* Updates global variable */ //STEP3 EXEC PGM=PROGRAM3

Variables defined outside any IF/THEN/ELSE blocks are globally accessible. Variables defined within conditional blocks are only accessible within that block and its nested blocks.

Exporting Variables Between Jobs

jcl
1
2
3
4
5
6
7
8
//EXPORT JOB (ACCT#),'ADMIN',CLASS=A // EXPORT SYMLIST=(TODAY,ENV) // SET TODAY=&SYSDATE // SET ENV='PROD' //* //STEP1 EXEC PGM=PROGRAM1 //* //STEP2 EXEC PGM=PROGRAM2

The EXPORT statement makes variables available to subsequent jobs in the same JES execution group.

Best Practices

  1. Centralize variable definitions at the beginning of the job for better readability
  2. Use meaningful variable names that indicate their purpose
  3. Comment variable definitions to explain complex values or calculations
  4. Set default values for variables that might not be provided externally
  5. Define constants as variables to make JCL more maintainable
  6. Validate variable values with conditional logic where appropriate
  7. Use computed variables instead of hard-coding calculated values
  8. Consider variable scope when defining and using variables

Troubleshooting

IssuePossible CausesSolutions
Variable not substituted
  • Variable name misspelled
  • Variable not defined in accessible scope
  • Syntax error in variable reference
  • Check variable name for typos
  • Ensure variable is defined before use
  • Verify & prefix is used when referencing
Calculation error
  • Division by zero
  • Overflow or underflow
  • Non-numeric data in arithmetic operation
  • Add validation checks before calculations
  • Use conditional logic to handle edge cases
  • Verify variable types before operations
Concatenation issues
  • Missing double period (..)
  • String becomes too long after concatenation
  • Quote mismatch in string values
  • Ensure double periods when concatenating with literal periods
  • Check resulting string length (max 255 characters)
  • Verify matching quotes for string literals
System symbols not available
  • System symbol not supported on your system
  • System symbol access restricted by installation
  • Check system documentation for available symbols
  • Use SYMLIST command to display defined symbols
  • Provide alternative defaults for missing symbols

Debugging Tips

  • Use SYMLIST command to display values of defined symbols
  • Set MSGLEVEL=(1,1) on the JOB statement to see expanded JCL with resolved variables
  • Add trace steps that write variable values to the job log for debugging
  • Use TYPERUN=SCAN to validate JCL with variables without execution
  • Check the system log for variable substitution errors

JES2 vs JES3 Considerations

  • Basic JCL variable functionality is supported in both environments
  • Some system-specific symbols may vary between JES2 and JES3
  • JES3 provides additional control through //*MAIN statement parameters
  • When migrating between JES environments, verify symbol availability

Related Concepts