Chapter 27 Quiz: JCL Essentials for COBOL Programmers

Test your understanding of Job Control Language concepts. Each question is followed by a hidden answer -- try to answer before revealing it.


Question 1

What are the three fundamental JCL statement types, and what does each do?

Show Answer The three fundamental JCL statement types are: 1. **JOB** (`//jobname JOB`): Marks the beginning of a job and defines job-level attributes such as accounting information, job class, message class, notification, region size, and time limit. 2. **EXEC** (`//stepname EXEC`): Identifies a program to execute (`PGM=`) or a procedure to invoke (`PROC=`). Each EXEC statement defines one job step. It can also specify step-level parameters like PARM, COND, REGION, and TIME. 3. **DD** (`//ddname DD`): Defines a dataset (file) used by a step. It connects the logical file names in your COBOL program (from ASSIGN TO) to physical datasets on the system. DD parameters specify the dataset name (DSN), access mode (DISP), space allocation (SPACE), and record format (DCB). All JCL statements begin with `//` in columns 1-2. Comments begin with `//*`.

Question 2

What does DISP=(NEW,CATLG,DELETE) mean?

A) Create a new dataset; catalog it if the step succeeds; delete it if the step abends B) Create a new dataset; catalog it always; delete it if not needed C) Open an existing dataset; catalog it if modified; delete it on close D) Create a new dataset; keep it temporarily; delete it at job end

Show Answer **A) Create a new dataset; catalog it if the step succeeds; delete it if the step abends** The three subparameters of DISP are: 1. **Status** (NEW): The dataset does not exist; create it 2. **Normal disposition** (CATLG): If the step completes normally, keep the dataset and add it to the catalog 3. **Abnormal disposition** (DELETE): If the step abends, delete the dataset This is the most common pattern for creating output files. It ensures that incomplete output from a failed step is cleaned up automatically, while successful output is preserved and cataloged for use by subsequent jobs.

Question 3

In the following COBOL program, what DD name must appear in the JCL?

       FILE-CONTROL.
           SELECT EMPLOYEE-MASTER
               ASSIGN TO EMPFILE.
Show Answer The DD name must be **EMPFILE**. The `ASSIGN TO` clause in the COBOL FILE-CONTROL paragraph specifies the external name that maps to a DD statement in the JCL:
//EMPFILE  DD  DSN=PROD.EMPLOYEE.MASTER,DISP=SHR
The DD name (EMPFILE) is the bridge between the COBOL program and the physical dataset on the system. If the DD name in the JCL does not match the ASSIGN TO name in the COBOL program, the program will receive an S013 abend (dataset open error) or a file status error when it tries to OPEN the file.

Question 4

What is the difference between DISP=SHR and DISP=OLD?

Show Answer **DISP=SHR** (Shared): Allows multiple jobs to read the dataset simultaneously. The system grants shared access (like a read lock). Multiple programs can have the file open at the same time for reading. **DISP=OLD** (Exclusive): Grants exclusive access to the dataset. No other job can access the dataset while this job has it allocated. This is required when a program will update the dataset, to prevent other programs from reading inconsistent data. Guidelines: - Use `DISP=SHR` for input files (read-only access) - Use `DISP=OLD` for files that will be updated (written, rewritten, or deleted) - If you code `DISP=OLD` on a file that only needs to be read, you unnecessarily block other jobs from accessing it

Question 5

True or False: When using the COND parameter COND=(4,LT,STEP01), the step is bypassed if STEP01's return code is less than 4.

Show Answer **False.** The COND parameter syntax is `COND=(code,operator,stepname)`, and the comparison is: **code operator stepname's-return-code** So `COND=(4,LT,STEP01)` means: "bypass this step if 4 is less than STEP01's return code" -- that is, **bypass if STEP01's RC is greater than 4**. The step is bypassed when STEP01 RC = 5, 6, 7, 8, ... (anything greater than 4). The step runs when STEP01 RC = 0, 1, 2, 3, or 4. The inverted logic of COND is one of the most confusing aspects of JCL, which is why the modern IF/THEN/ELSE/ENDIF construct is preferred for readability.

Question 6

What is the purpose of BLKSIZE=0 on a DCB parameter?

Show Answer **BLKSIZE=0** tells the operating system to calculate and use the optimal block size automatically, based on the device type and the logical record length (LRECL). On modern z/OS systems, the system-determined block size typically maximizes the number of records per track, which minimizes the number of I/O operations needed to read or write the file. This is almost always the correct choice and is recommended practice. For example, for a file with RECFM=FB and LRECL=200 on a 3390 device, the system might select a BLKSIZE of 27800 (139 records per block), which fits optimally in a single track. Coding a specific BLKSIZE is only necessary when interoperability with other systems requires a particular block size, or when the file is being transmitted to a non-z/OS platform.

Question 7

What does the following DD statement do?

//SYSLIB   DD  DSN=DEV.COBOL.COPYLIB,DISP=SHR
//         DD  DSN=PROD.COBOL.COPYLIB,DISP=SHR
//         DD  DSN=SYS1.COBOL.COPYLIB,DISP=SHR
Show Answer This is a **DD concatenation**. The second and third DD statements have no name (they are unnamed) and are therefore concatenated with the preceding named DD statement (SYSLIB). The program sees all three datasets as a single logical file. For the COBOL compiler, SYSLIB is the copybook library. When the compiler encounters a `COPY` statement, it searches the concatenated libraries in order: 1. First, it searches `DEV.COBOL.COPYLIB` 2. If not found, it searches `PROD.COBOL.COPYLIB` 3. If still not found, it searches `SYS1.COBOL.COPYLIB` The compiler uses the first match it finds. This allows development copybooks to override production versions during development, while falling back to production copies for unchanged members.

Question 8

What is the maximum length of a z/OS dataset name, and what characters are allowed?

Show Answer A z/OS dataset name can be a maximum of **44 characters** long (including the periods between qualifiers). Rules: - The name consists of one or more **qualifiers** separated by periods - Each qualifier can be **1 to 8 characters** long - Qualifiers must start with a **letter** (A-Z) or **national character** ($, #, @) - Remaining characters can be letters, digits (0-9), national characters, or hyphens - The total name including periods cannot exceed 44 characters Example: `PROD.PAYROLL.EMPLOYEE.MASTER` (4 qualifiers, 28 characters total) Most installations have naming conventions that use the first qualifier as a high-level qualifier (HLQ) to identify the project or application, followed by qualifiers for type, environment, and specific identity.

Question 9

What is a GDG, and how do relative generation numbers work?

Show Answer A **GDG (Generation Data Group)** is a collection of historically related sequential datasets managed under a single base name. Each dataset in the group is called a **generation** and is identified by an absolute generation number (e.g., G0045V00). **Relative generation numbers** provide a convenient way to reference generations: - **(0)** refers to the most current (newest) generation - **(-1)** refers to the previous generation - **(-2)** refers to two generations back - **(+1)** creates a new generation (one beyond the current) **Critical rule:** Relative generation numbers are resolved at **job start time**, not at step execution time. This means: - If step 1 creates `(+1)` and step 2 reads `(0)`, step 2 reads the generation that was current **before the job started**, not the one just created in step 1. - To read the newly created generation in a later step, use a **referback**: `DSN=*.STEP010.ddname`. GDGs are ideal for files created on a recurring schedule (daily transaction files, monthly reports, backup files) because they automatically manage retention, deleting the oldest generation when the configured limit is reached.

Question 10

Which IBM-supplied procedure compiles, link-edits, and executes a COBOL program in a single invocation?

A) IGYWC B) IGYWCL C) IGYWCLG D) IGYWPL

Show Answer **C) IGYWCLG** (Compile, Link-edit, and Go) The IBM-supplied COBOL procedures are: - **IGYWC**: Compile only - **IGYWCL**: Compile and Link-edit - **IGYWCLG**: Compile, Link-edit, and Go (execute) - **IGYWCG**: Compile and Go (no permanent load module) - **IGYWPL**: Compile, Pre-link, and Link-edit - **IGYWPLG**: Compile, Pre-link, Link-edit, and Go IGYWCLG is the most commonly used during development because it performs all three steps in one job. To override DD statements within the procedure, use the `procstep.ddname` format: `COBOL.SYSIN`, `COBOL.SYSLIB`, `GO.ddname`, etc.

Question 11

What happens if you code DISP=NEW without specifying the second and third subparameters?

Show Answer If you code only `DISP=NEW`, the defaults for the second and third subparameters are: - Normal disposition: **DELETE** - Abnormal disposition: **DELETE** This means the dataset will be **deleted** when the step ends, regardless of whether it completed successfully or abended. This is almost never the desired behavior for a real output file. **Always code at least the first two subparameters for new datasets:**
DISP=(NEW,CATLG,DELETE)
This is one of the most common JCL mistakes. A programmer creates a new output file with `DISP=NEW`, the program runs successfully and writes millions of records, and then the dataset is immediately deleted because the default normal disposition is DELETE.

Question 12

True or False: The PARM= parameter on an EXEC statement can pass up to 256 characters to a COBOL program.

Show Answer **False.** The maximum PARM length is **100 characters** (not 256). This is a hard limit imposed by the operating system. In the COBOL program, the PARM data is received via the PROCEDURE DIVISION USING clause. The data area has a 2-byte binary length prefix followed by the parameter string:
01  WS-PARM-DATA.
    05  WS-PARM-LENGTH  PIC S9(04) COMP.
    05  WS-PARM-STRING  PIC X(100).

PROCEDURE DIVISION USING WS-PARM-DATA.
If you need to pass more data to a program, use a parameter file (DD statement with `DD *` instream data or a dataset) rather than the PARM= parameter.

Question 13

What ABEND code indicates a "data exception" and is the most common COBOL abend?

A) S0C1 B) S0C4 C) S0C7 D) S0CB

Show Answer **C) S0C7 (Data Exception)** S0C7 occurs when a decimal instruction encounters invalid data in a field that is expected to contain valid packed decimal or zoned decimal numbers. Common causes in COBOL: 1. **Uninitialized numeric field**: A field defined as PIC 9 contains spaces or low-values because it was never moved to. 2. **Incorrect data in input file**: The input record has non-numeric characters in a position that the program treats as numeric. 3. **Group move corruption**: A group-level MOVE placed alphanumeric data over a numeric field. 4. **Subscript out of range**: An array subscript exceeds the table bounds, causing the program to read garbage data. 5. **Missing record**: Reading past end-of-file returns garbage data that is then used in arithmetic. Other common abend codes: S0C1 (operation exception), S0C4 (protection exception), S0CB (divide by zero), S013 (file open error), S806 (module not found).

Question 14

What is the purpose of DD DUMMY?

Show Answer **DD DUMMY** defines a null file that your program can open, read, and write without error, but no actual I/O occurs: - **READ** operations return end-of-file immediately - **WRITE** operations are accepted but discarded - **OPEN** and **CLOSE** succeed normally
//OPTFILE  DD  DUMMY
DD DUMMY is useful in several scenarios: 1. **Optional output files**: When you want to suppress report generation during a test run 2. **Conditional files**: When a file is sometimes needed and sometimes not, DUMMY prevents abends when it is not needed 3. **Testing**: When you want to test program logic without writing actual output 4. **Performance testing**: When you want to measure CPU time without I/O overhead It is functionally equivalent to `/dev/null` on Unix systems.

Question 15

What is the IF/THEN/ELSE/ENDIF construct, and why is it preferred over COND?

Show Answer IF/THEN/ELSE/ENDIF is the modern JCL construct for conditional execution, providing readable, positive-logic control flow:
// IF (STEP01.RC = 0) THEN
//STEP02  EXEC PGM=NEXTPROG
// ELSE
//ERRJOB  EXEC PGM=ERRNOTFY
// ENDIF
It is preferred over COND for several reasons: 1. **Positive logic**: IF specifies when a step SHOULD run, whereas COND specifies when a step should be SKIPPED. Positive logic is far easier to understand and maintain. 2. **Compound conditions**: IF supports AND (`&`), OR (`|`), and NOT operators for complex conditions: ```jcl // IF (STEP01.RC = 0 & STEP02.RC <= 4) THEN ``` 3. **ABEND testing**: IF can test for specific abend conditions: ```jcl // IF (STEP01.ABEND) THEN // IF (STEP01.ABENDCC = S0C7) THEN ``` 4. **Nesting**: IF/THEN/ELSE/ENDIF can be nested for multi-level decision trees. 5. **Readability**: The intent of the conditional logic is immediately clear, reducing the risk of coding errors.

Question 16

What is the difference between STEPLIB and JOBLIB?

Show Answer Both STEPLIB and JOBLIB tell the system where to find the load module (executable program) to run, but they differ in scope: **JOBLIB**: Coded immediately after the JOB statement, before the first EXEC. Applies to **all steps** in the job. The system searches JOBLIB for every program specified on an EXEC PGM= statement.
//MYJOB   JOB ...
//JOBLIB   DD  DSN=PROD.LOADLIB,DISP=SHR
//STEP01   EXEC PGM=PROG1
//STEP02   EXEC PGM=PROG2
**STEPLIB**: Coded within a step (after the EXEC statement). Applies to **that step only**. If both STEPLIB and JOBLIB are present, STEPLIB overrides JOBLIB for that step.
//STEP01   EXEC PGM=PROG1
//STEPLIB  DD  DSN=TEST.LOADLIB,DISP=SHR
**Search order for load modules:** STEPLIB (if present) > JOBLIB (if present and no STEPLIB) > System linklist (LPA and LNKLST). Use JOBLIB when all steps use the same load library. Use STEPLIB when different steps need different libraries or when you need to override the JOBLIB for a specific step.

Question 17

A programmer codes SPACE=(CYL,(5,2),RLSE). What does each part mean?

Show Answer - **CYL**: The allocation unit is cylinders (approximately 849,960 bytes per cylinder on a 3390 device) - **5**: The **primary** allocation is 5 cylinders. This is the initial space allocated when the dataset is created. - **2**: The **secondary** allocation is 2 cylinders. When the primary space is full, the system allocates an additional 2 cylinders. This can happen up to 15 times (on non-SMS volumes), so the maximum total space is 5 + (15 * 2) = 35 cylinders. - **RLSE**: **Release** unused space when the dataset is closed. If the program only uses 3 of the 5 primary cylinders, the remaining 2 cylinders are freed for other datasets. Other allocation units: - `TRK` (tracks): Approximately 56,664 bytes per track. Use for small files. - A number (e.g., `SPACE=(27800,...)`): Average block size in bytes. The system converts to tracks.

Question 18

What does the IEFBR14 program do, and why is it useful?

Show Answer **IEFBR14 does nothing.** It is a one-instruction program that immediately returns with a condition code of 0. Its source code is essentially:
IEFBR14 CSECT
        BR    14       (Branch to return address)
        END
It is useful because JCL dataset allocation and deletion happen as part of step initiation and termination, regardless of what the program does. By using IEFBR14, you can: **Allocate a new empty dataset:**
//ALLOC   EXEC PGM=IEFBR14
//NEWFILE DD  DSN=PROD.NEW.FILE,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(10,5)),
//            DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
**Delete an existing dataset:**
//DELETE  EXEC PGM=IEFBR14
//OLDFILE DD  DSN=PROD.OLD.FILE,
//            DISP=(OLD,DELETE,DELETE)
IEFBR14 is the standard utility for JCL-level dataset management tasks that do not require any program logic.

Question 19

What is the difference between RECFM=FB and RECFM=VB?

Show Answer **RECFM=FB (Fixed Blocked):** - Every record is the exact same length (specified by LRECL) - Records are grouped into blocks for efficient I/O - No record length information is stored with each record - This is the most common format for COBOL batch files - Example: LRECL=200 means every record is exactly 200 bytes **RECFM=VB (Variable Blocked):** - Records can have different lengths (up to the maximum specified by LRECL) - Each record has a 4-byte **Record Descriptor Word (RDW)** prefix containing the record length - Each block has a 4-byte **Block Descriptor Word (BDW)** prefix - LRECL specifies the maximum record length **including** the 4-byte RDW - Used when records naturally vary in length (e.g., text records, variable-length transaction records) For COBOL programming: - FB files use `RECORD CONTAINS n CHARACTERS` or `RECORDING MODE IS F` - VB files use `RECORD IS VARYING IN SIZE FROM min TO max` or `RECORDING MODE IS V` - The RDW and BDW are handled transparently by the system; the COBOL program does not see them

Question 20

True or False: A cataloged procedure stored in SYS1.PROCLIB can be overridden by placing a member with the same name in a library listed in the JCLLIB statement.

Show Answer **True.** The JCLLIB statement specifies the search order for procedures. Libraries listed in JCLLIB are searched before the system PROCLIB:
//MYLIBS  JCLLIB ORDER=(DEV.JCLLIB,SYS1.PROCLIB)
With this JCLLIB, when `EXEC COBCLG` is coded: 1. The system first searches `DEV.JCLLIB` for member COBCLG 2. If not found, it searches `SYS1.PROCLIB` This allows development teams to create their own versions of standard procedures without modifying the system PROCLIB. The development version takes precedence because it is searched first. JCLLIB must be coded immediately after the JOB statement (before any EXEC statements) and there can be only one JCLLIB statement per job.

Question 21

What system abend code indicates that a load module was not found, and what should you check to resolve it?

Show Answer **S806** indicates that the system could not find the specified load module. To resolve an S806 abend, check the following in order: 1. **Program name spelling**: Verify that the PGM= parameter matches the actual member name in the load library. Names are case-sensitive and must be exactly 1-8 characters. 2. **STEPLIB/JOBLIB**: Verify that the DD statement points to the correct load library: ```jcl //STEPLIB DD DSN=PROD.COBOL.LOADLIB,DISP=SHR ``` 3. **Library contents**: Verify the program exists in the specified library: ``` LISTDS 'PROD.COBOL.LOADLIB' MEMBERS ``` 4. **Link-edit step**: If the program was recently compiled, verify the link-edit step completed successfully and placed the load module in the correct library. 5. **System linklist**: If no STEPLIB or JOBLIB is coded, the system searches the linklist. Verify the program is in a linklist library. 6. **Authorization**: Verify you have READ access to the load library (S913 would indicate a security issue, but S806 can also occur if the library itself cannot be accessed).

Question 22

What is the purpose of the SET MAXCC = 0 command in IDCAMS, and when should you use it?

Show Answer `SET MAXCC = 0` resets the IDCAMS maximum condition code to zero. IDCAMS sets a non-zero condition code when a command fails or produces a warning. SET MAXCC overrides this so that subsequent JCL condition checks see a return code of 0. **Common usage:** Deleting a dataset that may or may not exist:
//CLEANUP  EXEC PGM=IDCAMS
//SYSPRINT DD  SYSOUT=*
//SYSIN    DD  *
  DELETE PROD.TEMP.FILE NONVSAM PURGE
  SET MAXCC = 0
/*
Without `SET MAXCC = 0`, if the dataset does not exist, IDCAMS returns RC=8 (not found error). This would cause subsequent COND checks to bypass later steps. By resetting to 0, you tell JCL, "I expected this might not exist, and that is OK." **Important:** Use SET MAXCC judiciously. Do not use it to suppress real errors. Only use it after operations where failure is an expected, acceptable outcome (such as deleting a dataset that may have been cleaned up by a previous run).

Question 23

What is the difference between SYSOUT=* and SYSOUT=A on a DD statement?

Show Answer **SYSOUT=*** directs the output to the same output class as the MSGCLASS parameter on the JOB statement. If MSGCLASS=X, then SYSOUT=* routes to class X. This is convenient because you do not need to know or hard-code the output class. **SYSOUT=A** directs the output to output class A specifically, regardless of the MSGCLASS setting. Class A is typically the default print class on many installations.
//MYJOB   JOB ...MSGCLASS=X,...
//STEP01  EXEC PGM=MYPROG
//RPTFILE DD  SYSOUT=*      Routes to class X (held output)
//PRTFILE DD  SYSOUT=A      Routes to class A (immediate print)
Output classes are installation-defined. Common conventions: - **A**: Immediate print - **X** or **H**: Held output (viewable in SDSF but not printed) - **Z**: Purged after viewing Using `SYSOUT=*` is the recommended practice because it inherits the job's output routing, making JCL more portable across environments.

Question 24

Explain the compilation return code thresholds for IBM Enterprise COBOL and what each level means.

Show Answer IBM Enterprise COBOL produces the following return codes: | RC | Level | Meaning | |---|---|---| | **0** | Success | Clean compilation. No warnings or errors. Object code is produced and reliable. | | **4** | W (Warning) | Informational warnings. Object code is produced and will almost certainly execute correctly. Common causes: truncation warnings, deprecated features. | | **8** | E (Error) | Errors detected. Object code IS produced, but the program may not execute correctly. The compiler made assumptions about what you intended. Review the errors. | | **12** | S (Severe) | Severe errors. **No object code is produced.** The link-edit step cannot proceed. The source must be corrected and recompiled. | | **16** | U (Unrecoverable) | Unrecoverable errors. Compilation was terminated early. This is rare and usually indicates a compiler issue or corrupted source. | In practice: - RC=0 or 4: Proceed to link-edit - RC=8: Review the listing carefully; the program likely has bugs - RC=12 or 16: Fix the source errors and recompile The standard COND parameter for the link step is `COND=(8,LT,COMPILE)`, which means "skip link if 8 < compile RC" -- skipping when RC is 12 or 16.

Question 25

True or False: When a COBOL program defines BLOCK CONTAINS 0 RECORDS in the FD entry, the system determines the optimal block size at runtime based on the device type.

Show Answer **True.** `BLOCK CONTAINS 0 RECORDS` in the COBOL FD entry tells the runtime system to use the block size specified in the JCL DCB parameter or the dataset label. When combined with `BLKSIZE=0` in the JCL (or no BLKSIZE at all for a new dataset), the system calculates the optimal block size based on the 3390 track geometry. This is the recommended practice because: 1. It decouples the COBOL program from device-specific characteristics 2. The system can optimize for the actual device where the file resides 3. If the file is later moved to a different device type, no code changes are needed 4. Modern z/OS systems choose block sizes that maximize track utilization The combination of `BLOCK CONTAINS 0 RECORDS` in COBOL and `BLKSIZE=0` in JCL is the modern standard for all new development.

Question 26

What is the purpose of the NAME control statement in the link-edit step, and what does the (R) mean?

//SYSLIN  DD  DSN=&&OBJMOD,DISP=(OLD,DELETE)
//        DD  *
  NAME PAYROLL(R)
/*
Show Answer The **NAME** control statement tells the linkage editor the name to assign to the output load module. In this case, the load module will be named **PAYROLL**. The **(R)** means **Replace**: if a member named PAYROLL already exists in the output load library (SYSLMOD), replace it with the new version. Without (R), the linkage editor would fail if the member already exists.
NAME PAYROLL(R)   Replace existing member
NAME PAYROLL      Fail if member already exists
In practice, (R) is almost always specified because you typically want to replace the old version with the newly compiled version. The NAME statement is coded as instream data concatenated after the object module input, so the linkage editor processes the object code first and then applies the NAME directive.

Question 27

A job creates DSN=PROD.PAYROLL.HISTORY(+1) in step 1 and needs to read this newly created dataset in step 3. How should the DD statement in step 3 reference the dataset?

Show Answer Use a **referback** to the step 1 DD statement:
//*  Step 1 - Create new GDG generation
//STEP01   EXEC PGM=PAYROLL
//OUTPUT   DD  DSN=PROD.PAYROLL.HISTORY(+1),
//             DISP=(NEW,CATLG,DELETE),
//             SPACE=(CYL,(10,5),RLSE),
//             DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//*
//*  Step 3 - Read the generation created in Step 1
//STEP03   EXEC PGM=REPORT
//INPUT    DD  DSN=*.STEP01.OUTPUT,DISP=SHR
The referback `DSN=*.STEP01.OUTPUT` tells the system to use the same dataset that was allocated to DD name OUTPUT in STEP01. This correctly references the newly created generation. **Do not** use `DSN=PROD.PAYROLL.HISTORY(0)` in step 3, because relative GDG numbers are resolved at **job start time**. At job start, `(0)` still points to the generation that was current before the job began, not the one created in step 1.

Question 28

What utility program would you use to compare two sequential datasets record by record to verify they are identical?

Show Answer **IEBCOMPR** is the standard z/OS utility for comparing two sequential datasets:
//COMPARE  EXEC PGM=IEBCOMPR
//SYSPRINT DD  SYSOUT=*
//SYSUT1   DD  DSN=PROD.FILE.ORIGINAL,DISP=SHR
//SYSUT2   DD  DSN=PROD.FILE.COPY,DISP=SHR
//SYSIN    DD  *
  COMPARE TYPORG=PS
/*
IEBCOMPR reads both files and compares them record by record (for sequential files with `TYPORG=PS`) or member by member (for PDS with `TYPORG=PO`). It reports the first 16 unequal comparisons and then terminates. Return codes: - RC=0: Files are identical - RC=8: Files differ (at least one unequal comparison found) - RC=12: Unrecoverable error - RC=16: User-requested termination For more sophisticated comparisons (ignoring specific columns, comparing only portions of records), DFSORT's ICETOOL VERIFY operation or a custom COBOL comparison program may be needed.

Question 29

What does the TYPRUN=SCAN parameter on the JOB statement do, and when would you use it?

Show Answer **TYPRUN=SCAN** causes JES to validate the JCL syntax without actually executing the job. The system performs: 1. JCL syntax checking (statement format, parameter validation) 2. Procedure expansion (resolves all PROC invocations and applies overrides) 3. Symbolic parameter substitution 4. Verification of DD statement syntax It does **not**: - Allocate datasets - Execute programs - Check if datasets actually exist - Verify RACF permissions
//MYJOB   JOB (ACCT01),'TEST RUN',
//             TYPRUN=SCAN
Use TYPRUN=SCAN when: - You have written new JCL and want to check for syntax errors before submitting - You are modifying a complex job with many procedures and want to verify the changes - You want to see the fully expanded JCL (including procedure expansions) without running the job - You are training and want to experiment with JCL syntax safely After verifying with SCAN, remove or change the TYPRUN parameter to actually run the job.

Question 30

A COBOL program uses RECORDING MODE IS F in the FD entry, but the JCL specifies DCB=(RECFM=VB,LRECL=204). What will happen?

Show Answer This is a **mismatch between the COBOL program and the JCL**, and it will likely cause a runtime error or incorrect results. The COBOL FD specifies fixed-length records (`RECORDING MODE IS F`), but the JCL specifies variable-length blocked records (`RECFM=VB`). The consequences depend on the operation: **For OPEN INPUT (reading):** If the file was actually written as VB, the COBOL program will interpret the 4-byte Record Descriptor Word (RDW) as part of the data, corrupting the first 4 bytes of each record. The program may also read incorrect record boundaries. **For OPEN OUTPUT (writing):** The program writes fixed-length records, but the system adds RDW headers (because RECFM=VB is specified), making each physical record 4 bytes longer than expected. Programs that subsequently read this file with the correct VB format will see records that are 4 bytes shorter than the LRECL. **Resolution:** The COBOL program and JCL must agree on the record format: - If the file should be fixed: Use `RECORDING MODE IS F` in COBOL and `RECFM=FB` in JCL - If the file should be variable: Use `RECORDING MODE IS V` in COBOL and `RECFM=VB` in JCL - The LRECL values must also be consistent (for VB, JCL LRECL includes the 4-byte RDW)