
There are scenarios where you need to check if the input is empty file before performing further actions. This ensures your program doesn’t waste CPU cycles processing this file or avoid abends due to unexpected input conditions. Mainframe utilities such as ICETOOL, FILEAID, IDCAMS, IEBPTPCH, ISRSUPC, and SORT set specific return codes when encountering an input file empty, enabling conditional execution using JCL IF/THEN logic.
Use cases for detection include:
- ✅ Check if a dataset is empty and skip all other steps.
- ✅ Conditionally skip steps if the input is empty using RC logic.
- ✅ Terminate jobs if total record count across datasets exceeds 5000.
- ✅ Handle files with header/trailer and optionally empty data segments.
Empty File Check using – ICETOOL
You can use ICETOOL’s COUNT operator to set a return code (RC) if a specified dataset is EMPTY, NOTEMPTY, HIGHER(n), LOWER(n), EQUAL(n), or NOTEQUAL(n). The RC can be customized using RC4, RC8, or RC12 operands. For example, if RC8 is used, ICETOOL sets RC=8 when the dataset is empty.
EMPTY Operation
The EMPTY operand of COUNT is used to stop STEP2 from executing if the input dataset is empty.
ICETOOL evaluates just one record and sets RC=8 (or custom RC) if the file is empty, otherwise RC=0.
//EMPTYCHK EXEC PGM=ICETOOL //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //IN DD DSN=YOUR.DATASET.NAME,DISP=SHR //TOOLIN DD * COUNT FROM(IN) EMPTY RC8 /* // IF STEP1.RC = 0 THEN //STEP2 EXEC PGM=YOURPGM // ENDIF
EMPTY Operation with OMIT: Use OMIT with EMPTY to ignore header/trailer records and count only data records.
ICETOOL sets RC=4 if only header and trailer exist.
//EMPTYCHK EXEC PGM=ICETOOL //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //INPUT DD DSN=YOUR.DATASET.NAME,DISP=SHR //TOOLIN DD * COUNT FROM(INPUT) EMPTY USING(HDTL) RC4 /* //HDTLCNTL DD * OMIT COND=(1,6,CH,EQ,C'HEADER',OR,1,7,CH,EQ,C'TRAILER') /* // IF S1.RC = 0 THEN //S2 EXEC PGM=YOURPGM // ENDIF
HIGHER(n) Operation
Skip a SORT operation if the total record count across multiple datasets exceeds a threshold (e.g., 5000).
//EMPTYCHK EXEC PGM=ICETOOL //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //CONCAT DD DSN=DATASET1,DISP=SHR // DD DSN=DATASET2,DISP=SHR // DD DSN=DATASET3,DISP=SHR //OUT DD DSN=YOUR.OUTPUT.FILE,DISP=... //TOOLIN DD * MODE STOP COUNT FROM(CONCAT) HIGHER(5000) SORT FROM(CONCAT) TO(OUT) USING(CTL1) /* //CTL1CNTL DD * SORT FIELDS=(25,8,BI,A) /*
Empty File Check Using – FILEAID
//EMPTYCHK EXEC PGM=FILEAID //INPUT DD DSN=XXXXXXX.INFILE,DISP=SHR //OUTPUT DD DSN=DUMMY, // DISP=(NEW,CATLG,DELETE), // UNIT=SYSDA //SYSOUT DD * //SYSPRINT DD SYSOUT=* //SYSLIST DD SYSOUT=* //SYSTOTAL DD SYSOUT=* //SYSIN DD DUMMY
OR
//EMPTYCHK EXEC PGM=FILEAID,REGION=0M //SYSPRINT DD SYSOUT=* //DD01 DD DSN=XXXXXXX.INFILE,DISP=SHR //DD01O DD SYSOUT=* //SYSIN DD * $$DD01 COPY COUNT=1 //*
Explanation: If the input file is empty, then this step will return a condition code (RC) of 08. If the file contains data, the step will return RC = 0. By trapping this return code in subsequent JCL steps, you can programmatically determine whether the input dataset was empty and take appropriate actions.
Empty File Check Using – IEBPTPCH
//EMPTYCHK EXEC PGM=IEBPTPCH //SYSUT1 DD DSN=XXXXXXX.INFILE, // DISP=SHR //SYSUT2 DD DUMMY //SYSPRINT DD SYSOUT=* //SYSIN DD * PRINT //*
If the input file is empty, this JCL step will return RC = 04. If the file contains records, the return code will be RC = 0. By evaluating the return code of this step, you can programmatically determine whether the input file was empty or not.
Empty File Check Using – IDCAMS
IDCAMS can inspect a dataset and set a return code based on whether records exist in the file. This method is commonly used for file validation in JCL.
Method 1: PRINT COUNT(1)
//EMPTYCHK EXEC PGM=IDCAMS //INPUT DD DSN=XXXXXXX.INFILE,DISP=SHR //SYSPRINT DD SYSOUT=* //SYSIN DD * PRINT INFILE(INPUT) CHARACTER COUNT(1) /*
Return Codes:
RC 0 = File has one or more records
RC 4 = File is empty
RC 12 = Dataset not cataloged or not found
Method 2: REPRO COUNT(1)
This method copies at most one record to a dummy file to verify dataset contents.
//STEP1 EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //INFILE DD DSN=YOUR.INPUT.FILE,DISP=SHR //OUTDD DD DUMMY //SYSIN DD * REPRO INFILE(INFILE) OUTFILE(OUTDD) COUNT(1) /*
Return Codes:
RC 0 = File has records
RC 4 = File is empty
Empty File Check using – ICETOOL
//EMPTYCHK EXEC PGM=ICETOOL //* //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //IN DD DSN=XXXXXXX.INFILE, // DISP=SHR //TOOLIN DD * COUNT FROM(IN) EMPTY //*
If the input file is empty, then this step will return RC = 12. If it is not empty, it will return RC = 0. By trapping this return code, you can determine whether the input file was empty.
Empty File Check using – SORT
//EMPTYCHK EXEC PGM=SORT,PARM='NULLOUT=RC4' //SYSOUT DD SYSOUT=* //SORTIN DD DSN=XXXXXXX.INFILE, // DISP=SHR //SORTOUT DD DUMMY //SYSIN DD * SORT FIELDS=COPY /*
If the input file is empty, then this step will return RC = 04. If it is not empty, it will return RC = 0. You can use this return code to conditionally control the execution of subsequent JCL steps.
Empty File Check using – ISRSUPC
//STEP0100 EXEC PGM=ISRSUPC //SYSPRINT DD SYSOUT=* //OUTDD DD SYSOUT=* //OLDDD DD DUMMY //NEWDD DD DSN=YOUR FILE IN QUESTION, // DISP=SHR //SYSIN DD DUMMY
If the input file is empty, then this step will return RC = 28. If it is not empty, it will return RC = 01. This is another useful method to check file emptiness using the ISRSUPC utility.
Allocate New File
Below mentioned JCLs using IEBGENER or IEFBR14 will generate the required file with the DCB parameters requested.
//EMPTYFL EXEC PGM=IEBGENER //SYSUT1 DD DUMMY, // DCB=(LRECL=80,BLKSIZE=0,RECFM=FB,DSORG=PS) //SYSUT2 DD DSN=XXXXX.YYYYY, // DISP=(NEW,CATLG,DELETE), // UNIT=SYSDA, // SPACE=(CYL(20,20),RLSE), // DCB=(LRECL=80,BLKSIZE=0,RECFM=FB,DSORG=PS) //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //SYSIN DD DUMMY
//EMPTYFL EXEC PGM=IEFBR14 //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //SYSDUMP DD SYSOUT=* //DD01 DD DSN=XXXXX.YYYYY, // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL(20,20),RLSE),UNIT=SYSDA, // DCB=(DSORG=PS,RECFM=FB,LRECL=80,BLKSIZE=0) //*
Best Practices
- Always use COUNT(1) or PRINT CHARACTER COUNT(1) to limit processing to one record.
- Standardize on one utility per shop (e.g., IDCAMS or ICETOOL) for consistency.
- Ensure DISP=SHR on input DD to avoid allocation errors.
- Test return codes thoroughly in your environment, as some sites map RC 12 to empty files with ICETOOL.
- Document the utility and RC mapping in your JCL standards.
By incorporating these utilities into your JCL, you can reliably detect empty datasets and orchestrate downstream processing with clear, maintainable steps.
Empty Existing File
Below mentioned JCLs will remove the content of an existing file without deleting it.
1. One way is to use a COBOL program that opens the file in input mode and reads until end-of-file, then reopens it in output mode and closes it—effectively emptying the file.
Alternatively, use JCL with IEBGENER as shown below:
//EMPTYFL EXEC PGM=IEBGENER //SYSUT1 DD DUMMY, // DCB=(LRECL=80,BLKSIZE=0,RECFM=FB,DSORG=PS) //SYSUT2 DD DSN=XXXXX.YYYYY, // DISP=OLD //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //SYSIN DD DUMMY
Here we have used a DUMMY file with attributes identical to the file we want to empty. The key is specifying DISP=OLD, which tells the system to keep the file and just overwrite its content (with nothing).
2. You can also use IDCAMS to achieve the same effect:
//EMPTYFL EXEC PGM=IDCAMS //DDDMMY DD DUMMY //DDOUT DD DSN=XXXXX.YYYYY, // DISP=OLD //SYSIN DD * REPRO IFILE(DDDMMY) OFILE(DDOUT) //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=*
3. You can use SORT as well, though utilities like IDCAMS and IEBGENER are preferred for clarity and control.
//EMPTYFL EXEC PGM=SORT //SORTIN DD DSN=XXXXX.YYYYY,DISP=SHR //SORTOUT DD DSN=XXXXX.YYYYY,DISP=OLD //SYSOUT DD SYSOUT=* //SYSIN DD * OPTION COPY OMIT COND=ALL /*
Summary
Detecting and emptying files in JCL is essential for building robust, efficient, and error-free batch jobs. Whether you’re using IDCAMS, IEBGENER, or DFSORT, the key is knowing when and how to use them correctly. By doing so, you improve your mainframe job flows and prevent downstream errors caused by unexpected data conditions.
