cheat sheet
JCL DD Statement
Comprehensive reference for the JCL DD statement: DSN, DISP, DCB, SPACE, UNIT, VOL=SER, concatenation, DUMMY, SYSOUT, KEYLEN.
JCL DD Statement — Deep Reference
What it is
The DD (Data Definition) statement is the JCL card that binds a ddname inside a program — the logical file the program opens — to a real dataset, in-stream data, SYSOUT class, or no-op. It is the single most parameter-dense statement in JCL, controlling allocation (SPACE, UNIT, VOL=SER), lifecycle (DISP), record format (DCB), and routing (SYSOUT, DUMMY, NULLFILE). JCL quick reference covers the surrounding JOB and EXEC syntax; this page goes deep on every DD keyword you will encounter in production batch.
Install
DD statements are part of the JCL language and ship with z/OS — there is nothing to install. Code them in any sequential dataset, PDS member, or in-stream and run them through JES2 / JES3 with the TSO SUBMIT command, the SDSF SE action, or zowe jobs submit.
SUBMIT 'ALICE.JCL.LIB(SAMPLEJOB)'
Output: (none — exits 0 on success)
Syntax
A DD statement starts in column 1 with //, a 1–8 character ddname in columns 3–10, the keyword DD, and then a list of keyword sub-parameters separated by commas. Continuation onto the next card requires // in columns 1–2 and a non-blank character no earlier than column 4; long parameter lists are usually split after a comma.
//ddname DD param1=value1,
// param2=value2,
// param3=(sub1,sub2)
Output: (none — exits 0 on success)
Essential keywords
| Keyword | Meaning |
|---|---|
DSN= (or DSNAME=) | Dataset name — cataloged, uncataloged, temp, GDG, member |
DISP= | Status, normal-end, abnormal-end disposition |
DCB= | Data Control Block — RECFM, LRECL, BLKSIZE, DSORG, KEYLEN |
SPACE= | Primary, secondary, directory blocks |
UNIT= | Device type (SYSDA, TAPE, 3390, …) |
VOL=SER= | Specific volume serial(s) |
LABEL= | Tape label / file position |
RECFM= / LRECL= / BLKSIZE= | DCB sub-parameters when given directly |
DSNTYPE= | LIBRARY (PDSE), PDS, HFS, LARGE, EXTREQ, EXTPREF |
EXPDT= / RETPD= | Expiration date / retention period |
SYSOUT= | Route to JES spool (class, optional output dest) |
DUMMY / DSN=NULLFILE | No I/O — open succeeds, EOF on first read |
KEYLEN= / KEYOFF= | Sequenced-key length and offset (VSAM, extended-format) |
STORCLAS= / MGMTCLAS= / DATACLAS= | SMS class overrides |
AVGREC= | SPACE primary/secondary measured in records (U/K/M units) |
FREE= | When to deallocate (END, CLOSE) |
DSN — dataset naming patterns
The DSN parameter names what the ddname refers to. Names follow the standard z/OS dataset naming rules — up to 44 characters, 1–22 qualifiers separated by ., each qualifier 1–8 characters of alphanumeric plus @#$, the first qualifier (HLQ) used by RACF to find the matching profile. Temporary, GDG, and PDS-member forms add syntax on top.
Cataloged dataset
When the dataset is in the master/user catalog (the normal case), give the name alone — z/OS resolves the unit and volume from the catalog.
//INFILE DD DSN=ALICE.PAYROLL.MASTER,DISP=SHR
Output: (none — exits 0 on success)
Uncataloged dataset
For a dataset that exists on a volume but is not cataloged, include UNIT and VOL=SER so the system can find it without consulting the catalog.
//INFILE DD DSN=ALICE.PAYROLL.MASTER,
// DISP=SHR,
// UNIT=SYSDA,
// VOL=SER=PRD001
Output: (none — exits 0 on success)
Generation Data Group (GDG) reference
GDG members are referenced by relative number — (0) is the current generation, (-1) the previous, (+1) a new generation created by this job. The base must already exist (defined with IDCAMS DEFINE GENERATIONDATAGROUP).
//* Most recent existing generation
//INFILE DD DSN=ALICE.SALES.HISTORY(0),DISP=SHR
//* Two generations back
//INFILE2 DD DSN=ALICE.SALES.HISTORY(-2),DISP=SHR
//* Create a new generation
//OUTFILE DD DSN=ALICE.SALES.HISTORY(+1),
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(50,10),RLSE),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//* Absolute generation name (rarely needed)
//INFILE3 DD DSN=ALICE.SALES.HISTORY.G0042V00,DISP=SHR
Output: (none — exits 0 on success)
Temporary datasets
A name beginning with && is a job-temporary dataset; allocated when the step needs it, kept until the disposition says otherwise, deleted automatically when the job ends if the system has nothing else holding it. Use them to pass data between steps in the same job.
//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=ALICE.INPUT,DISP=SHR
//SORTOUT DD DSN=&&SORTED,
// DISP=(NEW,PASS),
// SPACE=(CYL,(5,5)),
// DCB=(RECFM=FB,LRECL=80)
//STEP02 EXEC PGM=ALICEPGM
//INFILE DD DSN=&&SORTED,DISP=(OLD,DELETE)
Output: (none — exits 0 on success)
PDS / PDSE member
DSN=lib(member) opens one member of a partitioned dataset. The library can be a PDS, a PDSE (DSNTYPE=LIBRARY), or a load library; the member name is 1–8 chars.
//SYSPROC DD DSN=ALICE.REXX.LIB(ALICEX01),DISP=SHR
//SYSIN DD DSN=ALICE.JCL.LIB(SAMPLE),DISP=SHR
Output: (none — exits 0 on success)
Names with special characters
Quoted DSN with single quotes lets you embed special characters; uncommon outside test rigs but required when migrating from non-mainframe naming. Lowercase is allowed inside the quotes but z/OS folds the qualifiers to uppercase at allocation unless the dataset is SMS-managed and explicitly tagged for mixed case.
//ODD DD DSN='ALICE.QUOTED-NAME.DATA',DISP=SHR
Output: (none — exits 0 on success)
DISP — disposition
DISP is a three-part keyword giving the dataset's current status, what to do at normal step end, and what to do at abnormal step end. The first sub-parameter affects allocation; the second and third affect cleanup at step exit.
DISP=(status, normal-end, abnormal-end)
| Status | Meaning |
|---|---|
NEW | Allocate a new dataset; fails if it already exists |
OLD | Exclusive access to an existing dataset |
SHR | Shared (read) access — multiple jobs allowed |
MOD | Append to an existing dataset (or create if NEW) |
| Normal / abnormal | Meaning |
|---|---|
DELETE | Uncatalog and scratch (frees DASD) |
KEEP | Leave dataset on disk; do not change catalog state |
CATLG | Catalog the dataset (default for NEW with no second sub-parameter on SMS volumes) |
UNCATLG | Remove catalog entry, leave dataset on disk |
PASS | Hand off to a later step in the same job |
DISP truth table
DISP= | First step | After normal step end |
|---|---|---|
(NEW,CATLG,DELETE) | Allocate new, catalog | Keep + catalog on success, scratch on failure |
(NEW,KEEP) | Allocate new, uncataloged | Keep on disk, no catalog entry |
(OLD,DELETE) | Exclusive | Scratch the dataset |
(OLD,KEEP) | Exclusive | Leave alone |
(SHR,KEEP) | Shared read | Leave alone |
(MOD,CATLG) | Append (create if NEW) | Catalog if newly created |
(NEW,PASS) | Allocate, exclusive | Pass to next step (still NEW until terminal disp) |
//* Pattern: build a new output, keep on success, throw away on fail
//OUT DD DSN=ALICE.WORK.NEW,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(10,5)),
// DCB=(RECFM=FB,LRECL=80)
//* Pattern: read shared (multiple jobs may open it)
//IN DD DSN=ALICE.MASTER,DISP=SHR
//* Pattern: append to a log
//LOG DD DSN=ALICE.AUDIT.LOG,DISP=MOD
//* Pattern: pass a temp file between steps
//STEP1 EXEC PGM=PROG1
//OUT DD DSN=&&PASS,DISP=(NEW,PASS),
// SPACE=(CYL,(1,1)),DCB=(RECFM=FB,LRECL=80)
//STEP2 EXEC PGM=PROG2
//IN DD DSN=&&PASS,DISP=(OLD,DELETE)
Output: (none — exits 0 on success)
DCB — data control block
DCB describes the record format, length, and blocking. SMS-managed datasets pick up the missing pieces from the data class; non-SMS datasets and tape need everything explicit. Modern shops usually let BLKSIZE=0 so the system picks a half-track optimum.
DCB=(RECFM=FB,LRECL=80,BLKSIZE=0,DSORG=PS)
| Sub-parameter | Meaning |
|---|---|
RECFM=F | Fixed-length records |
RECFM=V | Variable-length records |
RECFM=FB | Fixed Blocked — multiple records per block |
RECFM=VB | Variable Blocked |
RECFM=FBA | FB + ANSI carriage control (first byte = print control) |
RECFM=VBA | VB + ANSI carriage control |
RECFM=U | Undefined — block = record (load libraries) |
LRECL=n | Record length in bytes (max 32760 for non-LARGE, 32756 for V) |
BLKSIZE=n | Block size; 0 lets the system pick system-determined |
DSORG=PS | Physical sequential |
DSORG=PO | Partitioned organisation (PDS) |
DSORG=DA | Direct |
DSORG=IS | Indexed sequential (legacy) |
Common DCB recipes
(* 80-byte source/JCL - classic *)
DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
(* 132-byte print/report *)
DCB=(RECFM=FBA,LRECL=133,BLKSIZE=0)
(* Variable data - typical EDI / text *)
DCB=(RECFM=VB,LRECL=255,BLKSIZE=0)
(* Long variable - max 32756 / 32760 minus 4 RDW *)
DCB=(RECFM=VB,LRECL=32756,BLKSIZE=0)
(* Load library *)
DCB=(RECFM=U,BLKSIZE=32760)
(* PDS source *)
DCB=(RECFM=FB,LRECL=80,DSORG=PO)
Output: (none — exits 0 on success)
Referencing another dataset's DCB
DCB=*.stepname.ddname copies DCB attributes from a previously-allocated DD in the same job; DCB=ALICE.MODEL.DS copies from a model dataset on disk.
//OUT DD DSN=ALICE.WORK.COPY,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(5,5)),
// DCB=*.STEP01.INFILE
Output: (none — exits 0 on success)
SPACE — DASD allocation
SPACE= requests primary and secondary allocations and (for PDS) a directory-block count. The unit is TRK (tracks), CYL (cylinders — recommended for anything non-trivial), or a record length for AVGREC-style allocation. Always code a secondary extent — a missing one is the most common cause of B37 / D37 abends.
SPACE=(unit, (primary, secondary, directory), RLSE, CONTIG, ROUND)
| Sub-parameter | Meaning |
|---|---|
TRK | Allocate in tracks |
CYL | Allocate in cylinders (1 cyl = 15 tracks on 3390) |
n | Record-length unit when AVGREC= is given |
(prim,sec) | Primary + secondary extents |
(prim,sec,dir) | Primary + secondary + PDS directory blocks |
RLSE | Release unused space at close (return to free pool) |
CONTIG | Primary must be one contiguous extent |
ROUND | Round to whole cylinders when AVGREC is in use |
MXIG | Take the largest available extent |
ALX | Take up to five largest extents |
Common SPACE recipes
(* Small sequential, release leftovers *)
SPACE=(TRK,(5,5),RLSE)
(* Medium sequential *)
SPACE=(CYL,(50,10),RLSE)
(* Large dataset, 16K records average *)
AVGREC=K,SPACE=(160,(100,50),RLSE)
(* Allocates space for ~100K records of 160 bytes *)
(* PDS with 100 directory blocks *)
SPACE=(CYL,(10,5,100))
(* Empty PDSE - directory count is meaningless *)
SPACE=(CYL,(10,5,0)),DSNTYPE=LIBRARY
Output: (none — exits 0 on success)
B37 / D37 / E37 abends
These are the three space-related allocation failures every batch programmer learns the hard way: B37 = no more secondary extents and the volume is full, D37 = primary too small and no secondary specified, E37 = volume has run out of extents and the dataset has reached the 16-extent (or 123-extent for SMS) limit. The fix is RLSE to free unused space, a larger primary, or splitting across multiple volumes.
(* Multi-volume on shared DASD *)
//BIG DD DSN=ALICE.HUGE.FILE,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(900,200),RLSE),
// UNIT=(SYSDA,4), (* up to 4 volumes *)
// VOL=(,,,4),
// DCB=(RECFM=FB,LRECL=80)
Output: (none — exits 0 on success)
UNIT and VOL=SER
UNIT= names a device class (esoteric name like SYSDA, or generic like 3390, or specific address 181); VOL=SER= pins the dataset to a specific volume. SMS-managed allocations use storage and management classes instead and you can omit both.
//* Allocate on a specific volume
//OUT DD DSN=ALICE.WORK,
// DISP=(NEW,CATLG,DELETE),
// UNIT=SYSDA,
// VOL=SER=WRK001,
// SPACE=(CYL,(10,5))
//* Multi-volume preallocation
//BIG DD DSN=ALICE.HUGE,
// DISP=(NEW,CATLG,DELETE),
// UNIT=(SYSDA,3),
// VOL=SER=(WRK001,WRK002,WRK003),
// SPACE=(CYL,(500,100))
//* Specific device address - rare
//TAPE DD DSN=ALICE.BACKUP,
// DISP=(NEW,CATLG,DELETE),
// UNIT=(0A80,DEFER),
// VOL=SER=ALICE1,
// LABEL=(1,SL)
Output: (none — exits 0 on success)
Device classes you will see
| UNIT value | Devices it covers |
|---|---|
SYSDA | Generic DASD (3390) |
SYSALLDA | All DASD types |
3390 | 3390 disk family |
TAPE | Tape — installation-defined esoteric |
CART | Cartridge tape |
VIO | Virtual I/O (in-storage) — temp datasets only |
In-stream data (DD *) and DD DATA
For small inputs you can put records right in the JCL. DD * ends at the next JCL card or the /* delimiter; DD DATA is identical except it does not stop at //, which is useful when the in-stream data itself contains JCL-looking records.
//SYSIN DD *
LISTCAT ENT(ALICE.PAYROLL.MASTER) ALL
/*
//* Custom delimiter when default conflicts with data
//SYSIN DD *,DLM=@@
// some text that starts like JCL
//* also fine
@@
//* Plain DD DATA - reads until //END
//SYSIN DD DATA
//STEP01 EXEC PGM=IEFBR14
//SYSPRINT DD SYSOUT=*
//END
Output: (none — exits 0 on success)
Concatenation
Multiple datasets can be concatenated to a single ddname so the program sees them as one logical input. Code the first DD with the ddname and parameters, then subsequent DDs with blank ddnames; all DSNs must have compatible attributes (matching RECFM/LRECL, or the largest must come first).
//* Three input datasets read as one
//SYSPROC DD DSN=ALICE.REXX.SITE,DISP=SHR
// DD DSN=SYS1.SBPXEXEC,DISP=SHR
// DD DSN=SYS1.SAXREXEC,DISP=SHR
//* Concatenating in-stream data and a dataset
//SYSIN DD *
LISTCAT ENT(ALICE.PAYROLL.MASTER) ALL
/*
// DD DSN=ALICE.IDCAMS.COMMANDS(MORE),DISP=SHR
Output: (none — exits 0 on success)
Concatenation rules
- Maximum 16 datasets per DD chain (255 for PDSE/USS files in some cases).
- Mix PDS and PS — the result is read as if it were one logical sequential file.
- Different
LRECLis allowed only when the largest is in the first concatenation. DCBis taken from the first DD unless overridden.- Concatenating
DUMMYshort-circuits the rest — never useful, but worth knowing.
DUMMY and NULLFILE
DUMMY (or DSN=NULLFILE) makes the OPEN succeed and every read return EOF, every write succeed silently. Use it to stub out optional inputs during testing or to discard an unused output.
//* Skip an input
//INFILE DD DUMMY
//* Equivalent
//INFILE DD DSN=NULLFILE
//* DCB attributes still apply (some programs check them)
//INFILE DD DUMMY,DCB=(RECFM=FB,LRECL=80)
//* Discard output
//OUTFILE DD DUMMY,DCB=(RECFM=FB,LRECL=80)
Output: (none — exits 0 on success)
SYSOUT — JES spool
SYSOUT= routes the output to the JES2/JES3 spool instead of a dataset. The class (a single letter usually A through Z or 0 through 9) selects the JES output queue; * inherits the MSGCLASS on the JOB card.
(* Default class = MSGCLASS *)
//SYSPRINT DD SYSOUT=*
(* Specific class - H is held output in most shops *)
//REPORT DD SYSOUT=H
(* With JES output writer and form *)
//PRINT DD SYSOUT=(A,,STD1)
(* Route to internal reader - submits the dataset as a job *)
//RDR DD SYSOUT=(*,INTRDR)
(* Hold for browse without printing *)
//HELD DD SYSOUT=*,OUTPUT=*.HELD
//HELD OUTPUT CLASS=X,DEST=HOLD
Output: (none — exits 0 on success)
Useful SYSOUT extras
| Parameter | Meaning |
|---|---|
COPIES=n | Print N copies |
DEST= | Route to a specific destination |
FORMS= | Specify a form ID |
FCB= | Forms Control Buffer |
CHARS= | Print character set (XEROX/3800 era) |
BURST=Y | Burst output (paper printers) |
HOLD=YES | Hold output for browse |
OUTLIM= | Limit lines before JES forces termination |
FREE=CLOSE | Spool to JES at CLOSE instead of step end |
KEYLEN / KEYOFF
These DCB sub-parameters describe a key field for indexed-sequential, VSAM-emulated, or extended-format sequential datasets. KEYLEN is the key length in bytes, KEYOFF is the byte offset from the start of the record where the key begins.
(* Sequential dataset with extended format and a key for use with SORTKEYS *)
//OUT DD DSN=ALICE.KEYED.DS,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(10,5)),
// DCB=(RECFM=FB,LRECL=100),
// KEYLEN=8,KEYOFF=0,
// DSNTYPE=EXTREQ
(* IDCAMS uses these on DEFINE CLUSTER instead - DD-level KEYLEN
is the rare case for non-VSAM indexed access *)
Output: (none — exits 0 on success)
SMS classes
When SMS (Storage Management Subsystem) is active most allocation decisions move from JCL to installation-defined classes. SMS uses ACS routines on the dataset name to pick STORCLAS (where on disk it goes), MGMTCLAS (backup, migration, retention) and DATACLAS (RECFM, LRECL, BLKSIZE, KEYLEN, KEYOFF, SPACE defaults). You can override any of them at JCL level.
//OUT DD DSN=ALICE.SMS.OUTPUT,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(10,5),RLSE),
// DATACLAS=DC80FB,
// STORCLAS=SCSTD,
// MGMTCLAS=MCRETN90
Output: (none — exits 0 on success)
EXPDT and RETPD
Retention controls let JES (and DFHSM) know when the dataset becomes eligible for deletion. EXPDT is an explicit expiration date; RETPD is a retention period in days. Common pattern for production data is RETPD=14 with HSM ML2 migration after 7 idle days.
//OUT DD DSN=ALICE.DAILY.BACKUP(+1),
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(50,10),RLSE),
// RETPD=14
(* "Never expire" - the convention *)
//OUT DD DSN=ALICE.PERMANENT,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(5,5)),
// EXPDT=99000
(* Never expire post-2000 - new convention *)
EXPDT=1999/365
Output: (none — exits 0 on success)
Common pitfalls
- Forgetting the secondary extent —
SPACE=(CYL,(10))with no secondary gets a B37/D37 the first time the data outgrows ten cylinders. Always code(prim,sec). DISP=NEWon a dataset that already exists — gets a JCL errorIGD17001IorIEC141I 013. UseDISP=OLD(orMOD) to reuse, or delete first with an IEFBR14 step.DISP=SHRto write — z/OS allows write through a SHR allocation; another job may corrupt your data. UseOLDfor any write-mode open.- In-stream
DD *and lowercase data — column 1 of in-stream data must be uppercase unless the JES2 parameterLOWERCASE=YESis in effect, otherwise the JES card scanner may flag it. UseDD DATA,DLM=@@for free-form text. - Mismatched LRECL in concatenation — opens succeed but reads truncate to the first DD's LRECL. Always put the largest LRECL first or use
DCB=(LRECL=largest)on the head DD. BLKSIZE=0on a non-SMS dataset — system-determined BLKSIZE only works for SMS-managed datasets or whenIGGCAS00/half-track defaults are enabled in PARMLIB. Outside SMS, code an explicit blocksize.DUMMYdoesn't satisfy a required input check — programs that re-verify their input via DSCB will see "no real DSN" and fail. Use a small empty dataset instead.- GDG
(+1)referenced in a later step withoutDISP=PASS— the new generation isn't catalogued until the job ends. CodeDISP=(NEW,PASS)thenDISP=(OLD,CATLG)(or rely onRETAINfor newer LE). - Tape datasets and
EXPDT=99000— on some shops this is interpreted as "never scratch", on others as a fixed-date in 1999. Use the unambiguousEXPDT=1999/365form. UNIT=AFF=otherdd— affinity makes the new DD use the same volume as another allocation. Forgetting it means a second tape mount; remembering it the wrong way means jobs block each other on the same drive.FREE=CLOSEand re-opening — once the dataset is freed at CLOSE, opening it again in the same step requires re-allocation. Most programs assume the DD stays bound for the step's life.- GDG generations and
DISP=MOD— never use MOD on a GDG(+1); the generation is created on first allocation, and the next step that references(+1)gets the same one (one generation, not two).
Sources
References consulted while writing this article. Links open in a new tab.
- IBM Documentation — DD statement (z/OS MVS JCL Reference) — Authoritative reference for DD parameters (DSN, DISP, SPACE, DCB, FREE, UNIT, VOL) used in this article.
Real-world recipes
Allocate a new performance-tuned PS dataset
A daily ingest job needs a large fixed-block sequential dataset with system-optimised blocking, generous secondary extents, and release-on-close to avoid wasted DASD.
//ALICEJ01 JOB (ACCT),'DAILY INGEST',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//STEP01 EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
//SYSUT1 DD DSN=ALICE.SRC.INPUT,DISP=SHR
//SYSUT2 DD DSN=ALICE.DAILY.LOAD,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(300,100),RLSE),
// DCB=(RECFM=FB,LRECL=200,BLKSIZE=0),
// DATACLAS=DC200FB,
// MGMTCLAS=MCRETN30,
// AVGREC=K
Output:
IEB352I WARNING: ONE OR MORE OF THE OUTPUT DCB PARMS COPIED FROM INPUT
IEB1135I IEBGENER PROCESSING ENDED AT EOD
Build then read a GDG with PASS
A two-step job creates a new generation in step 1 and reads it in step 2 without going through the catalog (which would only be updated at job end).
//ALICEJ02 JOB (ACCT),'GDG PIPELINE',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=ALICE.SRC.DAILY,DISP=SHR
//SORTOUT DD DSN=ALICE.SALES.HISTORY(+1),
// DISP=(NEW,PASS),
// SPACE=(CYL,(50,10),RLSE),
// DCB=(RECFM=FB,LRECL=80)
//SYSIN DD *
SORT FIELDS=(1,8,CH,A)
/*
//SYSOUT DD SYSOUT=*
//STEP02 EXEC PGM=ALICEPGM
//INFILE DD DSN=ALICE.SALES.HISTORY(+1),DISP=(OLD,CATLG)
//SYSOUT DD SYSOUT=*
Output:
ICE000I 1 - CONTROL STATEMENTS FOR SORT - LEVEL 12.0
ICE201I H RECORD TYPE IS F - DATA STARTS IN POSITION 1
ICE751I 1 - EFL-K06032: 0 IN: 142811 OUT: 142811
Multi-volume large dataset
A retention archive needs to span up to four DASD volumes; use UNIT=(SYSDA,4) and VOL=(,,,4) for the volume count.
//ARCHIVE DD DSN=ALICE.ARCHIVE.HUGE,
// DISP=(NEW,CATLG,DELETE),
// UNIT=(SYSDA,4),
// VOL=(,,,4),
// SPACE=(CYL,(2000,500),RLSE),
// DCB=(RECFM=VB,LRECL=32756,BLKSIZE=0),
// MGMTCLAS=MCARCHV
Output: (none — exits 0 on success)
Submit a downstream job via internal reader
A scheduler job builds a child JCL on the fly and pushes it to the internal reader; JES picks it up and queues it like any other submission.
//ALICEJ03 JOB (ACCT),'SUBMIT CHILD',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//SUB EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
//SYSUT1 DD *
//ALICEJ04 JOB (ACCT),'CHILD',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//STEP01 EXEC PGM=IEFBR14
//DD1 DD DSN=ALICE.CHILD.SCRATCH,
// DISP=(NEW,DELETE,DELETE),
// SPACE=(TRK,(1,1)),
// DCB=(RECFM=FB,LRECL=80)
/*
//SYSUT2 DD SYSOUT=(*,INTRDR)
Output:
IEB352I WARNING: ONE OR MORE OF THE OUTPUT DCB PARMS COPIED FROM INPUT
IEB1135I IEBGENER PROCESSING ENDED AT EOD
$HASP100 ALICEJ04 ON INTRDR CHILD
Discover the optimal BLKSIZE for an existing dataset
Use IDCAMS LISTCAT to inspect the actual block size SMS picked for a similar dataset, then reuse it on the next allocation.
//LISTCAT EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
LISTCAT ENT('ALICE.MODEL.DS') ALL
/*
Output:
NONVSAM ------- ALICE.MODEL.DS
IN-CAT --- CATALOG.MASTER
HISTORY
DATASET-OWNER-----ALICE CREATION-----------26.140
RELEASE----------------2 EXPIRATION----------00.000
SMSDATA
STORAGECLASS ---SCSTD MANAGEMENTCLASS-MCRETN30
DATACLASS ------DC200FB LBACKUP ---0000.000.0000
ATTRIBUTES
RECORG---NULL RECFM----FB
LRECL------------200 BLKSIZE--------27800
KEYLEN----------NULL RKP-------------NULL
EXTENTS-----------1 EXTHIGH-----------12
Concatenate a per-job override library in front of the site library
A common DevOps pattern — let the developer's PDS take precedence over the site library so a hotfix can be tested without changing the shared copy.
//SYSPROC DD DSN=ALICE.MY.REXX,DISP=SHR (* developer override *)
// DD DSN=SYS1.SBPXEXEC,DISP=SHR
// DD DSN=SYS1.SAXREXEC,DISP=SHR
Output: (none — exits 0 on success)
Capture step output even if the step abends
Wrap a problem job with FREE=CLOSE and a SYSOUT class that doesn't get purged on abend so you can still read the spool.
//STEP01 EXEC PGM=ALICEPGM
//SYSPRINT DD SYSOUT=X,FREE=CLOSE
//SYSUDUMP DD SYSOUT=X,FREE=CLOSE
//SYSIN DD DSN=ALICE.INPUT,DISP=SHR
//OUTFILE DD DSN=ALICE.OUTPUT,
// DISP=(NEW,CATLG,KEEP), (* KEEP on abend so partial output stays *)
// SPACE=(CYL,(10,5),RLSE),
// DCB=(RECFM=FB,LRECL=200)
Output: (none — exits 0 on success)