LOAD is not a TSO command you type once. On z/OS it runs as a batch job: JCL starts DSNUTILB, DD statements name every file, and SYSIN holds the LOAD control statement. This page shows a complete DB2 LOAD JCL skeleton, what each DD is for, and the mistakes that cause RC=8 before a single row is loaded.
Online utilities share one batch program: DSNUTILB. The EXEC PARM names the subsystem ID and a utility ID (UID) that must be unique while the utility is active. IBM’s cataloged procedure DSNUPROC wraps DSNUTILB so you set SYSTEM= and UID= instead of coding PGM= yourself.
123//LOADJOB JOB (ACCT),'DB2 LOAD',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID //LOAD EXEC DSNUPROC,SYSTEM=DB2T,UID='HR.LOAD.EMP',UTPROC='' //* Equivalent idea: EXEC PGM=DSNUTILB,PARM='DB2T,HR.LOAD.EMP'
STEPLIB (or JOBLIB) must include the Db2 SDSNLOAD library for that subsystem’s runtime. Mixing SDSNLOAD from the wrong release is a classic “why did DSNUTILB abend at once?” error. UTPROC left blank means a new execution, not a restart of a stopped utility.
| DD name | Role | Required? |
|---|---|---|
| SYSIN | LOAD control statements | Yes |
| SYSPRINT | Utility messages | Yes |
| SYSREC | Input records (INDDN default) | Yes (unless INCURSOR) |
| SYSERR | Error work file (ERRDDN default) | Yes |
| SYSMAP | Row-id to input-record map (MAPDDN) | When discards + unique indexes or ENFORCE |
| SYSDISC | Discarded input records (DISCARDDN) | If you want discards kept |
| SYSUT1 | Sort input (WORKDDN first name) | If indexes are built |
| SORTOUT | Sort output (WORKDDN second name) | If indexes are built |
| UTPRINT | Sort utility messages | Recommended |
| SYSCOPY | Inline image copy if COPYDDN SYSCOPY | If you take an inline copy |
Rename any of these with INDDN, ERRDDN, MAPDDN, DISCARDDN, WORKDDN, or COPYDDN in the control statement—then the JCL DD (or TEMPLATE) must use that new name. Defaults exist so IBM samples and shop standards stay readable.
123456789101112131415161718192021222324252627282930//LOADJOB JOB (ACCT),'DB2 LOAD',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID //LOAD EXEC DSNUPROC,SYSTEM=DB2T,UID='HR.LOAD.EMP',UTPROC='' //SYSREC DD DISP=SHR,DSN=HR.EMPLOYEE.SYSREC //SYSDISC DD DSN=HR.EMPLOYEE.SYSDISC, // DISP=(MOD,DELETE,CATLG),UNIT=SYSDA, // SPACE=(CYL,(10,5),RLSE) //SYSERR DD DSN=HR.EMPLOYEE.SYSERR, // DISP=(MOD,DELETE,CATLG),UNIT=SYSDA, // SPACE=(CYL,(5,5),RLSE) //SYSMAP DD DSN=HR.EMPLOYEE.SYSMAP, // DISP=(MOD,DELETE,CATLG),UNIT=SYSDA, // SPACE=(CYL,(5,5),RLSE) //SYSUT1 DD DSN=HR.EMPLOYEE.SYSUT1, // DISP=(MOD,DELETE,CATLG),UNIT=SYSDA, // SPACE=(CYL,(20,10),RLSE) //SORTOUT DD DSN=HR.EMPLOYEE.SORTOUT, // DISP=(MOD,DELETE,CATLG),UNIT=SYSDA, // SPACE=(CYL,(20,10),RLSE) //UTPRINT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //SYSIN DD * LOAD DATA INDDN SYSREC REPLACE DISCARDDN SYSDISC DISCARDS 100 ERRDDN SYSERR MAPDDN SYSMAP WORKDDN(SYSUT1,SORTOUT) INTO TABLE HR.EMPLOYEE (EMPNO POSITION(1:6) CHAR, LASTNAME POSITION(7:21) CHAR) /*
IBM samples often use DISP=(MOD,DELETE,CATLG) on work files so a restart can append, a successful job deletes them from the catalog path you chose, and a failure keeps them. Match SPACE to input size: SYSDISC should be able to hold the whole SYSREC if everything is rejected.
Sequential, BSAM-readable. Tape, DASD, or an HFS/zFS file via TEMPLATE PATH. If SYSREC is on tape and work files use TEMPLATE, IBM tells you to include SPACE on those templates. Concatenation is allowed when you load several files of the same layout.
SYSDISC copies rejected input records—same LRECL as SYSREC. SYSERR is the error work file (always allocate it). SYSMAP correlates a table row identifier with the input record that caused an index or RI problem; skip it only when IBM says it is optional for your options (no unique indexes, no ENFORCE, no discards).
Index keys are sorted here. Undersize them and DFSORT fails in BUILD. SORTNUM / SORTDEVT in the control statement can allocate extra sort work (SORTWKnn / SWnnWKmm) dynamically; you still need the WORKDDN pair.
DSNUPROC fills in SYSPRINT, STEPLIB, and often UTPRINT. When you EXEC DSNUPROC, extra DDs are often coded as //DSNUPROC.SYSREC DD ... so they override the procedure. If you EXEC PGM=DSNUTILB yourself, you must supply STEPLIB to SDSNLOAD, SYSPRINT, SYSIN, and every work file. Both are correct; shops pick one standard.
12345678//LOAD EXEC PGM=DSNUTILB,PARM='DB2T,HR.LOAD.EMP' //STEPLIB DD DISP=SHR,DSN=DB2T.SDSNLOAD //SYSPRINT DD SYSOUT=* //UTPRINT DD SYSOUT=* //SYSREC DD DISP=SHR,DSN=HR.EMPLOYEE.SYSREC //SYSIN DD * LOAD DATA REPLACE INTO TABLE HR.EMPLOYEE /*
Put TEMPLATE statements in SYSIN before LOAD to build GDG or timestamped data set names for SYSREC, SYSDISC, or COPYDDN. Inline COPY during LOAD needs a COPYDDN data set (often named SYSCOPY in older JCL). That copy is recorded in SYSIBM.SYSCOPY like a COPY utility output and is the usual way to avoid COPY-pending after LOG NO.
12345//SYSIN DD * TEMPLATE CPY DSN HR.EMP.&TS..D&DATE..T&TIME. LOAD DATA REPLACE LOG NO COPYDDN CPY NOCOPYPEND INTO TABLE HR.EMPLOYEE /*
The next pages cover UNLOAD (which often builds the SYSREC and SYSPUNCH this JCL consumes) and COPY/RECOVER, which protect you after a bad REPLACE.
JCL is the shopping list and the kitchen. DSNUTILB is the cook. SYSIN is the recipe (LOAD … INTO TABLE). SYSREC is the grocery bag of ingredients. SYSDISC is the plate for food that came out wrong. SYSERR and SYSMAP are the cook’s notes about which potato caused the problem. SYSUT1 and SORTOUT are extra counter space for sorting index cards. The UID is the order number so if the oven stops, you can say “continue order HR.LOAD.EMP” instead of starting a new cake.
1. Which program runs online Db2 utilities such as LOAD?
2. Default DD name for LOAD input data?
3. SYSUT1 and SORTOUT are used for:
4. Why must SYSDISC match SYSREC LRECL?
5. PARM on DSNUTILB typically contains: