Mainframe Path Start learning free
Core9 min readLesson 3 of 4

Datasets and TSO commands from REXX

REXX becomes really useful when it talks to z/OS: allocating datasets, reading and writing records with EXECIO, running TSO commands and capturing their output, and running all of it unattended in batch.

Reading a dataset with EXECIO

Read every record into a stem
/* REXX */
"ALLOC FI(INDD) DA('PROD.PAY.REPORT') SHR REUSE"
"EXECIO * DISKR INDD (STEM rec. FINIS"
if rc <> 0 then say 'Read failed, RC' rc
say rec.0 'records read'
do i = 1 to rec.0
  if pos('ERROR', rec.i) > 0 then say rec.i
end
"FREE FI(INDD)"

Text in quotes that REXX does not recognise is passed to the current environment — in TSO, that means it runs as a TSO command. DISKR reads, DISKW writes, and FINIS closes the file.

Capturing command output

OUTTRAP
x = outtrap('out.')
"LISTCAT LEVEL(USER.PAY)"
x = outtrap('OFF')
do i = 1 to out.0
  if word(out.i,1) = 'NONVSAM' then say word(out.i,3)
end

Handy TSO functions

Running in batch

IKJEFT01 runs REXX unattended
//RUNREXX  EXEC PGM=IKJEFT01
//SYSEXEC  DD DISP=SHR,DSN=USER.REXX
//SYSTSPRT DD SYSOUT=*
//SYSTSIN  DD *
  CHKRPT PROD.PAY.REPORT
/*

Reading a dataset, line by line

REXXWhat it means
"ALLOC FI(INDD) DA('PROD.PAY.REPORT') SHR REUSE"
Allocate the dataset to the DD name INDD, shared. REUSE replaces any earlier allocation of INDD.
"EXECIO * DISKR INDD (STEM rec. FINIS"
Read every record into rec.1, rec.2 …, then close the file.
say rec.0 'records read'
rec.0 holds the number of records read.
"FREE FI(INDD)"
Release the allocation so other jobs are not blocked.

Try it yourself

TRY IT YOURSELF

After EXECIO reads a file into the stem rec., which variable holds the number of records?

Show a hint

By convention, element zero of a stem is the count.

Show the solution

rec.0

Common mistakes

Unquoted dataset names

In TSO, a name without single quotes gets your user ID added as a prefix. Use DA('FULL.NAME') with the quotes.

Forgetting FINIS and FREE

Files left open or allocated cause enqueue problems for other jobs. Close and free what you allocate.

Reading huge files into one stem

EXECIO * on millions of records uses a lot of storage. Read in chunks with a count instead of *.

What you will see at work

Key terms

Check your understanding.
Take this lesson's quiz and save your progress. Free.

Take the lesson quiz
← Decisions, loops and PARSEISPF edit macros and error handling →