Showing posts with label mainframe COBOL. Show all posts
Showing posts with label mainframe COBOL. Show all posts

Thursday, 14 August 2014

COBOL Terminal Input and Output: ACCEPT and DISPLAY Examples

COBOL terminal input output flow using ACCEPT and DISPLAY
ACCEPT reads input. DISPLAY writes output.

A small test job asks for an account number, the operator types one line, and the program prints the value to the spool. In COBOL, that simple exchange is usually built with two verbs: ACCEPT for input and DISPLAY for output.

This page explains terminal input and output in COBOL in plain English. It focuses on what a beginner sees in a batch job, TSO test, or training program: where the input comes from, where the message goes, and why these verbs should be used carefully in production code.

What Terminal Input and Output Means in COBOL

Terminal input and output means the program communicates with a person or a simple run-time device instead of reading a normal business file. In a mainframe batch job, input can come from SYSIN. Output often goes to SYSOUT, the job log, or a console-related destination depending on the compile and run-time setup.

That is different from file processing. A file program normally uses OPEN, READ, WRITE, and CLOSE with an FD entry. Terminal I/O is simpler, but it is not a replacement for structured file design. Use it for prompts, diagnostics, small utilities, classroom examples, and controlled test jobs.

ACCEPT Verb in COBOL

The ACCEPT statement moves incoming data into a COBOL data item. IBM documents that ACCEPT does not validate or edit the incoming value for you, so the program must check the field after reading it. If the user enters letters into a numeric account field, your program needs to decide what to do.

Simple ACCEPT Syntax

WORKING-STORAGE SECTION.
01  WS-ACCOUNT-NO        PIC X(10).
01  WS-REPLY             PIC X.

PROCEDURE DIVISION.
    DISPLAY "ENTER ACCOUNT NUMBER: ".
    ACCEPT WS-ACCOUNT-NO.

    DISPLAY "ACCOUNT ENTERED: " WS-ACCOUNT-NO.
    STOP RUN.

In a simple batch test, the value accepted by the program can be supplied through SYSIN. That lets a developer repeat the same test without typing at a screen every time.

Batch Test with SYSIN

//STEP01   EXEC PGM=ACCTIO
//STEPLIB  DD DISP=SHR,DSN=PROD.COBOL.LOAD
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
ACCT000123
/*

When the program executes ACCEPT WS-ACCOUNT-NO, the run-time environment can read the next available input line from the assigned input source. Site standards vary, so always check how your shop maps COBOL terminal input in batch, TSO, and z/OS UNIX runs.

DISPLAY Verb in COBOL

The DISPLAY statement writes literals and data items to an output device. With no special destination phrase, the output normally goes to the system logical output device. In a batch job, that usually means the message appears in spool output associated with SYSOUT.

Simple DISPLAY Syntax

01  WS-ACCOUNT-NO        PIC X(10) VALUE "ACCT000123".
01  WS-STATUS            PIC X(08) VALUE "ACTIVE".

PROCEDURE DIVISION.
    DISPLAY "ACCOUNT=" WS-ACCOUNT-NO
            " STATUS=" WS-STATUS.
    STOP RUN.

This is useful for small trace messages while testing. For example, a developer may display the key before a READ, then display the file status after the READ. For long-running production jobs, permanent logging rules should come from your team standard rather than scattered DISPLAY statements.

ACCEPT and DISPLAY Together

The pair is easy to understand when shown together. The program below reads an employee number and prints a clean response. It also checks that the field is not blank before continuing.

IDENTIFICATION DIVISION.
PROGRAM-ID. TERMIO.

DATA DIVISION.
WORKING-STORAGE SECTION.
01  WS-EMP-NO            PIC X(08).

PROCEDURE DIVISION.
    DISPLAY "ENTER EMPLOYEE NUMBER: ".
    ACCEPT WS-EMP-NO.

    IF WS-EMP-NO = SPACES
        DISPLAY "EMPLOYEE NUMBER IS REQUIRED"
    ELSE
        DISPLAY "EMPLOYEE NUMBER ENTERED: " WS-EMP-NO
    END-IF.

    STOP RUN.

The validation is deliberately simple. In a real payroll or claims program, you might also check length, allowed characters, and whether the key exists in a VSAM file or Db2 table.

Common Uses in Mainframe Work

Use case Typical verb Example
Read one test value ACCEPT Read an account number from SYSIN.
Print a diagnostic message DISPLAY Show WS-FILE-STATUS after a failed read.
Confirm selected options DISPLAY Print the run date, region, or control-card value.
Build a quick training program Both Prompt for a value, accept it, and display the result.

Validation Rules Beginners Often Miss

ACCEPT is not the same as business validation. It reads the data, but it does not prove the data is right. For a numeric field, accept into an alphanumeric work field first when bad input is possible, check it, and only then move it to a numeric field.

01  WS-AMOUNT-TEXT       PIC X(07).
01  WS-AMOUNT            PIC 9(07).

PROCEDURE DIVISION.
    DISPLAY "ENTER AMOUNT: ".
    ACCEPT WS-AMOUNT-TEXT.

    IF WS-AMOUNT-TEXT IS NUMERIC
        MOVE WS-AMOUNT-TEXT TO WS-AMOUNT
        DISPLAY "AMOUNT ACCEPTED: " WS-AMOUNT
    ELSE
        DISPLAY "AMOUNT MUST BE NUMERIC"
    END-IF.

This avoids a common beginner mistake: reading untrusted input directly into a numeric field and then wondering why the program fails later or prints confusing output.

DISPLAY Output Limits and Formatting

Keep displayed lines short. IBM documents device-related limits for displayed records, and console output is especially limited compared with ordinary spool output. A safe training habit is to display concise messages and split long diagnostic text across several lines.

DISPLAY "INPUT ACCOUNT: " WS-ACCOUNT-NO.
DISPLAY "FILE STATUS  : " WS-FILE-STATUS.
DISPLAY "ACTION       : CHECK CUSTOMER MASTER".

Avoid one huge DISPLAY line containing every field in working storage. It is hard to read in spool output, and it can be split by the output device. Short messages are easier to scan during an abend review.

ACCEPT vs READ in COBOL

Use ACCEPT when the program needs a small value from a simple input source. Use READ when the program processes records from a defined file. A batch payment program should not use ACCEPT to process thousands of payment records; it should define the input file in the Environment Division and read it record by record.

For file processing topics, continue with the Mainframe Forum guides on COBOL READ statement, COBOL file status, and COBOL OPEN statement.

How This Fits with Other COBOL Verbs

ACCEPT and DISPLAY are often the first COBOL I/O verbs a learner sees. After that, the next step is usually file input and output, then table processing, string handling, and conditional logic. Related Mainframe Forum notes include COBOL ACCEPT statement, COBOL DISPLAY statement, COBOL PERFORM statement, and COBOL data types.

Common Mistakes

Accepting Bad Data Without a Check

If a field must be numeric, test it before moving it to a numeric target. If the field must be a valid code, compare it with known values or a control table.

Using DISPLAY as a Permanent Audit Trail

DISPLAY is fine for training and controlled diagnostics. For production audit evidence, use the logging method approved for the application so operations teams can search and retain it properly.

Mixing Terminal I/O with File I/O

Do not use ACCEPT for normal transaction files just because it looks shorter than READ. File I/O gives you record definitions, file status checks, and clearer restart behavior.

FAQ

What is the COBOL terminal input verb?

The common terminal input verb is ACCEPT. It reads data from an input source and places it into the named COBOL data item.

What is the COBOL terminal output verb?

The common terminal output verb is DISPLAY. It writes literals or data-item values to the output destination used by the run-time environment.

Can ACCEPT validate input automatically?

No. ACCEPT reads the input value, but the program must validate it. Use checks such as IS NUMERIC, blank checks, valid-code checks, or file/table lookups.

Should production batch programs use ACCEPT for large input files?

No. Large business input should usually be handled with normal file processing: OPEN, READ, file status checks, and CLOSE.

References

For exact syntax and current compiler behavior, use IBM documentation for Enterprise COBOL ACCEPT statement, Enterprise COBOL DISPLAY statement, and assigning input from a screen or file.

Use ACCEPT for small controlled input, use DISPLAY for readable messages, and validate every value that can come from outside the program.

Tuesday, 12 August 2014

COBOL EXIT Statement: EXIT, EXIT PROGRAM, GOBACK, and STOP RUN

A called COBOL program should return to its caller. A main batch program should end the run unit. A paragraph used by PERFORM THRU may only need a named end point. Those are three different jobs, and using EXIT, EXIT PROGRAM, GOBACK, or STOP RUN in the wrong place can leave the next developer staring at confusing control flow.

COBOL EXIT statement diagram comparing EXIT, EXIT PROGRAM, GOBACK, and STOP RUN
Pick the right ending point.

What does EXIT mean in COBOL?

The plain EXIT. statement is mainly a common end point. IBM treats the simple form like CONTINUE, so control can pass through it when no active PERFORM range is returning from that point. It is not the same as ending a program.

The confusion comes from the word itself. In daily language, exit means leave. In COBOL, EXIT., EXIT PROGRAM, EXIT PARAGRAPH, and EXIT SECTION each have their own rules.

EXIT, EXIT PROGRAM, GOBACK, and STOP RUN

Statement Main use What happens
EXIT. Named end point Acts like a no-operation point in the procedure flow.
EXIT PROGRAM Called program return Returns control to the statement after the active CALL.
GOBACK Main or called program ending Returns from a subprogram like EXIT PROGRAM; in a main program it ends like STOP RUN.
STOP RUN End the run unit Terminates the run unit and closes files for programs in that run unit.

Plain EXIT example

Older COBOL often uses an exit paragraph at the end of a performed range. The paragraph gives PERFORM paragraph-a THRU paragraph-exit a clear final point.

PROCEDURE DIVISION.
PERFORM 2000-VALIDATE-ORDER
THRU 2000-VALIDATE-EXIT
GOBACK.
2000-VALIDATE-ORDER.
IF ORDER-NUMBER = SPACES
MOVE "Y" TO WS-ERROR-SW
END-IF.
2000-VALIDATE-EXIT.
EXIT.

The EXIT. paragraph does not return to a caller by itself. The active PERFORM controls the return. If some other path falls into that paragraph without an active performed range, control can pass to the next paragraph.

EXIT PROGRAM example

Use EXIT PROGRAM in a called program when it has finished and should return to the caller. This is common in reusable validation, formatting, and lookup modules.

IDENTIFICATION DIVISION.
PROGRAM-ID. VALDCUST.
PROCEDURE DIVISION USING LK-CUSTOMER-REC LK-RETURN-CODE.
IF LK-CUSTOMER-ID = SPACES
MOVE 8 TO LK-RETURN-CODE
EXIT PROGRAM
END-IF
MOVE 0 TO LK-RETURN-CODE
EXIT PROGRAM.

When a CALL is active, EXIT PROGRAM returns to the statement after the call. In a main program with no active call, it should not be used as the normal ending statement.

GOBACK example

GOBACK is often used as a clean final statement because it works naturally in both main programs and called programs. In a called program, it returns to the caller. In a main program, it returns control to the system or caller of the main program.

PROCEDURE DIVISION.
PERFORM 1000-OPEN-FILES
PERFORM 2000-PROCESS-FILE
PERFORM 9000-CLOSE-FILES
GOBACK.

Many shops prefer GOBACK at the end of batch programs because it avoids changing the statement when the same program structure is reused as a subprogram.

STOP RUN example

STOP RUN ends the COBOL run unit. That makes it a poor choice inside a called utility program, because it can end more than the current program.

PROCEDURE DIVISION.
IF WS-FATAL-ERROR
MOVE 12 TO RETURN-CODE
STOP RUN
END-IF.

Use STOP RUN only when the program really should terminate the run unit. For normal subprogram return, use EXIT PROGRAM or GOBACK.

EXIT PARAGRAPH and EXIT SECTION

Enterprise COBOL also supports procedure forms such as EXIT PARAGRAPH and EXIT SECTION. These statements leave the current paragraph or section without running the remaining statements in that paragraph or section. They are useful for clear early-exit logic when the coding standard permits them.

3000-CHECK-INPUT.
IF INPUT-STATUS NOT = "00"
MOVE 8 TO RETURN-CODE
EXIT PARAGRAPH
END-IF
PERFORM 3100-VALIDATE-FIELDS.

Do not hide business logic behind too many early exits. One or two clear exits can make code easier to read. A paragraph full of exit paths becomes hard to test.

Common mistakes

Using EXIT when EXIT PROGRAM is needed

EXIT. does not end a called program. If the program must return to the caller, use EXIT PROGRAM or GOBACK.

Using STOP RUN in a subprogram

A subprogram should usually return to its caller. STOP RUN can end the run unit, so it may close files and stop processing outside the subprogram.

Depending on PERFORM THRU everywhere

PERFORM THRU and exit paragraphs appear in many older systems, but they can make control flow harder to follow. For new code, a single performed paragraph or inline PERFORM is often easier to maintain.

Practical coding checklist

  • Use EXIT. only as a clear common end point.
  • Use EXIT PROGRAM when a called program must return to the active CALL.
  • Use GOBACK when the program ending should work in both main and called contexts.
  • Use STOP RUN only when the whole run unit should end.
  • Keep end points easy to scan in the Procedure Division.

Related Mainframe Forum guides

For related control-flow topics, read COBOL PERFORM statement, COBOL STOP RUN statement, COBOL CONTINUE and NEXT SENTENCE, COBOL CALL statement, and COBOL ending and reentering.

External references

IBM documents the Enterprise COBOL EXIT statement, EXIT PROGRAM format, GOBACK behavior, and STOP RUN behavior.

FAQ

Does EXIT end a COBOL program?

No. Plain EXIT. is mainly a common end point. Use EXIT PROGRAM, GOBACK, or STOP RUN when program ending behavior is required.

What is the difference between EXIT and EXIT PROGRAM?

EXIT. marks a procedure point and acts like no operation. EXIT PROGRAM returns from a called program to the statement after the active CALL.

Should I use GOBACK or STOP RUN?

Use GOBACK when the program should return cleanly from either a main or called context. Use STOP RUN only when the run unit should end.

Is EXIT PARAGRAPH the same as EXIT PROGRAM?

No. EXIT PARAGRAPH leaves the current paragraph. EXIT PROGRAM leaves the called program and returns to the caller.

Monday, 28 July 2014

COBOL PERFORM UNTIL: TEST BEFORE, TEST AFTER, and Loop Examples

A file-reading loop usually stops when the end-of-file flag becomes true. In COBOL, that pattern is often written with PERFORM UNTIL: run the statements again and again until the condition is satisfied.
COBOL PERFORM UNTIL loop showing TEST BEFORE and TEST AFTER behavior
PERFORM UNTIL stops when the condition is true.

This guide explains the UNTIL phrase of the COBOL PERFORM statement with simple examples. It keeps the focus on loop control: the condition, TEST BEFORE, TEST AFTER, inline loops, paragraph loops, and the mistakes that cause endless loops.

What PERFORM UNTIL Means

PERFORM UNTIL repeats a block of code or a named paragraph until a condition is true. IBM documents that when the condition is true, control passes to the next executable statement after the PERFORM.

PERFORM UNTIL END-OF-FILE
READ CUSTOMER-FILE
AT END
SET END-OF-FILE TO TRUE
NOT AT END
PERFORM 200-PROCESS-CUSTOMER
END-READ
END-PERFORM.

The loop continues while END-OF-FILE is false. It stops after the READ reaches end of file and the program sets the condition-name to true.

PERFORM UNTIL Syntax

The inline form keeps the looped statements directly under the PERFORM. It ends with END-PERFORM, which makes the loop boundary easy to see.

PERFORM [WITH TEST BEFORE | WITH TEST AFTER]
UNTIL condition
statement-1
statement-2
END-PERFORM.

The out-of-line form runs a paragraph or a range of paragraphs until the condition becomes true.

PERFORM 300-CALCULATE-TOTAL
UNTIL WS-DONE = "Y".

TEST BEFORE Is the Default

If you do not code WITH TEST BEFORE or WITH TEST AFTER, COBOL assumes TEST BEFORE. The condition is checked before the first execution. If the condition is already true, the loop body does not run at all.

MOVE 6 TO WS-COUNT.

PERFORM WITH TEST BEFORE
UNTIL WS-COUNT > 5
DISPLAY "COUNT=" WS-COUNT
ADD 1 TO WS-COUNT
END-PERFORM.

This loop displays nothing because WS-COUNT > 5 is already true before the loop starts. That behavior is correct, but it surprises many beginners.

TEST AFTER Runs at Least Once

WITH TEST AFTER checks the condition after the statements run. That means the body runs at least once, even when the condition is already true at entry.

MOVE 6 TO WS-COUNT.

PERFORM WITH TEST AFTER
UNTIL WS-COUNT > 5
DISPLAY "COUNT=" WS-COUNT
ADD 1 TO WS-COUNT
END-PERFORM.

This loop displays one line for COUNT=6, then stops. Use TEST AFTER only when one execution is required, such as prompting once before checking whether the user wants to continue.

File Reading Example

The most common mainframe use is a file loop. The file status and end-of-file flag should be initialized before the loop, then changed inside the loop.

01 WS-CUSTOMER-STATUS PIC X(02).
01 WS-END-OF-FILE PIC X VALUE "N".
88 END-OF-FILE VALUE "Y".
88 MORE-RECORDS VALUE "N".
PROCEDURE DIVISION.
SET MORE-RECORDS TO TRUE.
PERFORM UNTIL END-OF-FILE
READ CUSTOMER-FILE
AT END
SET END-OF-FILE TO TRUE
NOT AT END
PERFORM 200-PROCESS-CUSTOMER
END-READ
END-PERFORM.

This pattern is readable because the condition says what stops the loop. The loop does not depend on a hidden counter or an unclear flag name.

Counter Loop Example

PERFORM UNTIL can also control a counter. Initialize the counter before the loop and change it inside the loop. Without the change, the loop can run forever.

MOVE 1 TO WS-SUB.

PERFORM UNTIL WS-SUB > 10
DISPLAY "TABLE ENTRY " WS-SUB
ADD 1 TO WS-SUB
END-PERFORM.

For a pure counter loop, PERFORM VARYING may be clearer. Use the plain UNTIL form when the stop condition is tied to a flag, file status, response code, or business rule.

Inline PERFORM vs Paragraph PERFORM

FormUse it whenWatch for
Inline PERFORM UNTILThe loop body is short and belongs in one place.Use END-PERFORM and keep nested statements readable.
Paragraph PERFORM UNTILThe loop body is reused or has a clear paragraph name.Avoid wide THRU ranges that make control flow hard to follow.

IBM notes that Enterprise COBOL supports both inline and out-of-line PERFORM. For modern code, a short inline loop is often easier to read, while a named paragraph can still be useful for a business step such as 200-PROCESS-CUSTOMER.

PERFORM UNTIL EXIT

UNTIL EXIT creates a loop that does not end from a normal condition. IBM warns that the program must reach a real escape path. In an inline loop, that usually means EXIT PERFORM.

PERFORM UNTIL EXIT
ACCEPT WS-REPLY
IF WS-REPLY = "Q"
EXIT PERFORM
END-IF
PERFORM 100-HANDLE-REPLY
END-PERFORM.

Use this form sparingly. A named condition such as UNTIL END-OF-FILE or UNTIL WS-REPLY = "Q" is usually easier for the next developer to inspect.

Common Mistakes

Forgetting to Change the Loop Condition

If the condition never becomes true, the loop never ends. Update the counter, set the end-of-file flag, or change the response field inside the loop.

Using TEST AFTER by Accident

TEST AFTER guarantees one execution. That is useful only when one pass is required. For file reads and most validation loops, TEST BEFORE is usually safer.

Hiding Logic in a Wide THRU Range

PERFORM A-PARA THRU Z-PARA can execute every paragraph between those names. Keep paragraph ranges tight, or use inline PERFORM when the loop belongs in one place.

Related COBOL Lessons

For the broader loop family, read COBOL PERFORM statement, COBOL basic PERFORM, COBOL PERFORM TIMES phrase, and PERFORM VARYING in COBOL. For condition logic, continue with COBOL IF statement and COBOL EVALUATE statement.

FAQ

What is PERFORM UNTIL in COBOL?

PERFORM UNTIL repeats a block of statements or a paragraph until the specified condition becomes true.

Is TEST BEFORE or TEST AFTER the default?

TEST BEFORE is the default. COBOL checks the condition before the first execution unless WITH TEST AFTER is coded.

When should I use TEST AFTER?

Use TEST AFTER when the loop body must run at least once, such as asking for input once before checking whether the user wants to quit.

How do I prevent an endless PERFORM UNTIL loop?

Initialize the condition before the loop and make sure the loop body can make the condition true. For file loops, set an end-of-file flag in the AT END path.

References

For exact syntax and current compiler behavior, use IBM documentation for PERFORM with UNTIL phrase, using PERFORM, and IBM's coding a loop examples.

Write the condition so it says exactly when the loop must stop, then make sure the code inside the loop can make that condition true.

COBOL SORT Procedure: USING, GIVING, INPUT, and OUTPUT Examples

A COBOL program can sort records inside the program with the SORT statement. That is useful when the program must select records before sorting or handle sorted records one at a time after sorting. For a simple production file sort, a separate JCL DFSORT step is often easier to tune and support, but internal COBOL SORT still has a place.

COBOL SORT procedure diagram showing input file, sort work file, output file, RELEASE, and RETURN
Sort, then process records.

What does COBOL SORT do?

The COBOL SORT statement arranges records or table elements in a sequence defined by one or more keys. For file sorting, COBOL uses an SD sort-file description, receives records from an input file or input procedure, sorts them, and then writes them to an output file or passes them to an output procedure.

Simple SORT USING GIVING example

The simplest form uses USING for the input file and GIVING for the output file. COBOL opens, reads, writes, and closes those files as part of the SORT. IBM notes that the input and output files named in these phrases must not already be open when the SORT executes.

SELECT INPUT-FILE  ASSIGN TO INFILE.
SELECT SORT-FILE   ASSIGN TO SORTWK.
SELECT OUTPUT-FILE ASSIGN TO OUTFILE.

SD  SORT-FILE.
01  SORT-REC.
    05 SORT-ACCOUNT-NO     PIC X(10).
    05 SORT-DATE           PIC X(8).
    05 SORT-AMOUNT         PIC S9(9)V99 COMP-3.

PROCEDURE DIVISION.
    SORT SORT-FILE
       ON ASCENDING KEY SORT-ACCOUNT-NO
       USING INPUT-FILE
       GIVING OUTPUT-FILE
    GOBACK.

This form fits a direct file-to-file sort where every input record should appear in the sorted output and no custom record logic is needed inside the COBOL program.

When to use INPUT PROCEDURE

Use INPUT PROCEDURE when records must be selected, edited, or built before the sort begins. The input procedure reads or creates records and sends each accepted record to the sort file with RELEASE.

SORT SORT-FILE
   ON ASCENDING KEY SORT-ACCOUNT-NO
   INPUT PROCEDURE 2000-BUILD-SORT-RECS
   GIVING OUTPUT-FILE.

2000-BUILD-SORT-RECS.
    PERFORM UNTIL END-OF-FILE
       READ INPUT-FILE
          AT END
             SET END-OF-FILE TO TRUE
          NOT AT END
             IF IN-STATUS = 'A'
                MOVE INPUT-REC TO SORT-REC
                RELEASE SORT-REC
             END-IF
       END-READ
    END-PERFORM.

Use this pattern when the program must drop inactive records, change field layouts, or combine working-storage values before the sort sees the record.

When to use OUTPUT PROCEDURE

Use OUTPUT PROCEDURE when sorted records must be processed before they are written. The output procedure gets each sorted record with RETURN. IBM recommends coding RETURN ... AT END and running until the end condition is reached.

SORT SORT-FILE
   ON ASCENDING KEY SORT-ACCOUNT-NO
   USING INPUT-FILE
   OUTPUT PROCEDURE 3000-WRITE-REPORT.

3000-WRITE-REPORT.
    PERFORM UNTIL NO-MORE-SORT-RECS
       RETURN SORT-FILE
          AT END
             SET NO-MORE-SORT-RECS TO TRUE
          NOT AT END
             MOVE SORT-REC TO REPORT-REC
             WRITE REPORT-REC
       END-RETURN
    END-PERFORM.

This form fits sorted reports, grouped totals, break processing, and cases where the program must inspect the sorted stream before writing the final output.

RELEASE and RETURN in plain English

Statement Where it is used Purpose
RELEASE Input procedure Sends one record to the sort file before sorting starts.
RETURN Output procedure Gets one sorted record from the sort file after sorting finishes.
AT END RETURN statement Detects that no more sorted records are available.

COBOL SORT vs JCL SORT

Use internal COBOL SORT when selection, transformation, or report logic belongs naturally in the program. Use JCL SORT when the requirement is only to sort, copy, include, omit, reformat, or split files. A separate DFSORT step is usually easier for operations teams to tune because sort memory, work files, and control statements are visible in JCL.

Common mistakes

Opening files before SORT USING or GIVING

Do not open the files named in USING or GIVING before the SORT. The SORT statement handles those files for that form.

Forgetting RELEASE in the input procedure

An input procedure must release records to the sort file. If no records are released, the output procedure or output file will not receive the expected data.

Forgetting RETURN AT END

An output procedure should keep returning sorted records until the AT END condition is reached. With DFSORT, failing to reach the end condition can lead to an abnormal sort termination.

Using internal SORT for every large file

Large high-volume sorts should be reviewed carefully. If the sort can be done outside the program, a JCL SORT step may be simpler to monitor and change.

Review checklist

  • Define the sort file with an SD entry.
  • Choose one input path: USING or INPUT PROCEDURE.
  • Choose one output path: GIVING or OUTPUT PROCEDURE.
  • Use RELEASE for records passed into an input procedure.
  • Use RETURN ... AT END for records pulled from an output procedure.
  • Compare internal COBOL SORT with a separate DFSORT step for high-volume batch work.

Related Mainframe Forum guides

For related topics, read JCL SORT examples, SORT INREC and OUTREC examples, COBOL sequential file organization, COBOL READ statement, and COBOL PERFORM statement.

External references

IBM documents the Enterprise COBOL SORT statement, coding the output procedure, and coding the input procedure.

FAQ

What is COBOL SORT used for?

COBOL SORT arranges records or table elements by one or more keys. For files, it can take input from files or an input procedure and send sorted records to files or an output procedure.

What is INPUT PROCEDURE in COBOL SORT?

INPUT PROCEDURE runs before sorting. It selects or builds records and passes them to the sort file with RELEASE.

What is OUTPUT PROCEDURE in COBOL SORT?

OUTPUT PROCEDURE runs after sorting. It gets each sorted record with RETURN and can write, total, or report the record.

Should I use COBOL SORT or JCL SORT?

Use COBOL SORT when program logic must run before or after sorting. Use JCL SORT when the task is mainly file sorting, copying, filtering, or formatting.

Sunday, 22 September 2013

COBOL Working Storage vs Local Storage: Key Differences

COBOL Working Storage vs Local Storage comparison showing persistent values and fresh copy per call
Working Storage keeps state; Local Storage starts fresh for each call.

A COBOL subprogram can return cleanly on the first call and fail on the second because a counter, switch, or table entry kept its old value in WORKING-STORAGE. Move the same item to LOCAL-STORAGE, and COBOL allocates a fresh copy for each call. That is the practical difference developers need before debugging a strange rerun or CALL problem.

Short rule: Working Storage persists for the run unit unless the program is initialised again. Local Storage is allocated for each invocation and freed when the program returns.

Working Storage vs Local Storage Comparison

Question Working Storage Local Storage
Scope Visible to the program that defines it. Visible to the program or method invocation that defines it.
Initialisation VALUE clauses are applied when the run unit starts, or when the program is reinitialised after CANCEL or INITIAL. VALUE clauses are applied on each call or method invocation. Without VALUE, the initial content is undefined.
Persistence between CALL statements Usually keeps the last-used value between calls in the same run unit. Does not keep values after return. A new copy is allocated for the next invocation.
When to use Use for program-level state that must remain available across paragraphs or repeated calls. Use for temporary work fields that should start fresh for each call, especially in reusable subprograms.

What Working Storage Means in COBOL

WORKING-STORAGE SECTION is part of the COBOL Data Division. It defines fields that belong to the program and remain available while the program is active in the run unit. A batch driver that calls the same subprogram many times can therefore see old values if the subprogram keeps counters, switches, or save areas in Working Storage and does not reset them.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-CALL-COUNT        PIC 9(4) VALUE ZERO.
01 WS-LAST-CUSTOMER     PIC X(10).

PROCEDURE DIVISION.
    ADD 1 TO WS-CALL-COUNT
    DISPLAY 'CALL COUNT=' WS-CALL-COUNT
    GOBACK.

If this program is called three times in the same run unit, WS-CALL-COUNT can show 1, then 2, then 3. That is useful when the program intentionally tracks state. It is a bug when the field was meant to be temporary.

What Local Storage Means in COBOL

LOCAL-STORAGE SECTION defines fields that are allocated when the program or method is invoked and freed when it returns. This makes Local Storage a good fit for scratch variables in reusable routines, recursive-style logic, and programs that may run in multiple invocations.

DATA DIVISION.
LOCAL-STORAGE SECTION.
01 LS-ITEM-AMOUNT       PIC 9(5) VALUE ZERO.
01 LS-WORK-FLAG         PIC X    VALUE 'N'.

PROCEDURE DIVISION.
    MOVE 'Y' TO LS-WORK-FLAG
    GOBACK.

On the next call, LS-WORK-FLAG is allocated again and the VALUE clause is applied again. That behavior is often safer for work fields that should not remember a previous transaction, customer, or input record.

CALL Behavior That Causes Runtime Errors

The easiest trap is a subprogram called repeatedly from a driver. A field in Working Storage keeps its last value, so a flag that should start as N might still be Y. A table index might still point past the last loaded entry. A previous customer number might leak into the next calculation.

Use Working Storage when that persistence is intentional. Use Local Storage when each call should start with a clean set of work fields. If a program uses PROGRAM-ID. name IS INITIAL, or if the caller issues CANCEL before calling again, Working Storage can be reinitialised, but that is a program-control decision and should not be hidden inside a variable naming habit.

Threading Difference

In environments where the same program can run in multiple simultaneous invocations, Working Storage can be shared by those invocations, while Local Storage gives each invocation a separate copy. That difference matters in CICS and other multi-tasking designs. If a field belongs to one transaction, request, or invocation, Local Storage is usually the safer place.

Where This Fits in the Data Division

Both sections belong to the COBOL Data Division, along with File Section and Linkage Section. For a broader layout of the Data Division, see the COBOL Data Division guide. If your bug is about fields passed between a caller and subprogram, also review the COBOL CALL statement and parameter passing guide.

Common Mistakes

  • Putting a temporary transaction flag in Working Storage and forgetting to reset it before every call.
  • Assuming Local Storage keeps a value after GOBACK.
  • Using VALUE clauses as a substitute for explicit reset logic in a long-running program.
  • Treating CANCEL as harmless when the called program relies on Working Storage persistence.

Practical Rule

If the value must survive the next call, use Working Storage and reset it deliberately when needed. If the value belongs only to this invocation, use Local Storage so old data cannot sneak into the next run path.

COBOL Application Structure: Main Program, Subprograms, and Run Unit

A payroll batch job rarely has only one COBOL program. One program reads the employee file, another validates pay codes, another calculates deductions, and a final report step prints totals for payroll control. Together, those programs form the COBOL application that the batch job runs.

COBOL application structure diagram with main program subprograms files DB2 and reports
Keep the modules clear.

What is a COBOL application?

A COBOL application is a group of programs, files, screens, database calls, reports, and job steps that work together to complete one business task. The task can be payroll, policy renewal, account posting, claim processing, statement printing, or a month-end batch process.

The old version of this page used an employee management example. That is still a useful way to picture the idea: employee registration, salary calculation, daily requests, and reporting can be separate modules in one application. Each module has a smaller job, but the application owns the full business result.

COBOL application versus COBOL program

A COBOL program is one compiled source member with divisions such as IDENTIFICATION DIVISION, ENVIRONMENT DIVISION, DATA DIVISION, and PROCEDURE DIVISION. A COBOL application is bigger than one program. It can include many COBOL programs and can also call programs written in other Language Environment member languages.

Item Meaning Example
Program One COBOL source member that is compiled. PAYMAIN, PAYCALC, PAYRPT
Application A set of programs and resources that complete a business process. Payroll processing for one pay cycle
Run unit One or more object programs that work together at run time. PAYMAIN calling PAYCALC and TAXCALC

Main program and subprograms

IBM describes the first COBOL program in a run unit as the main program. Other COBOL programs in that run unit are subprograms. There is no special source statement that marks a program as main or subprogram; the role depends on how the program enters the run unit.

This matters when the code ends or returns control. A main program normally finishes the run unit with STOP RUN or by returning to the caller outside that run unit. A subprogram usually returns control to the calling program with GOBACK or EXIT PROGRAM, depending on the coding standard used by the site.

Simple payroll application design

Here is a small payroll-style layout that a support developer might see in a batch application.

Program Role Main input or output
PAYMAIN Controls the run, reads employee records, and calls other modules. Employee master file
PAYVALD Checks employee status, department, and pay code. Validation return code
PAYCALC Calculates gross pay, tax, deduction, and net pay. Calculated payroll fields
PAYRPT Writes accepted, rejected, and control-total report lines. SYSOUT report

How the main program controls the flow

The main program should make the application flow easy to read. It opens files, loops through records, calls smaller modules, handles return codes, writes output, and closes files.

IDENTIFICATION DIVISION.
PROGRAM-ID. PAYMAIN.

PROCEDURE DIVISION.
    PERFORM OPEN-FILES
    PERFORM UNTIL WS-END-OF-FILE = 'Y'
        PERFORM READ-EMPLOYEE
        IF WS-END-OF-FILE NOT = 'Y'
            CALL 'PAYVALD' USING EMP-REC WS-VALID-RC
            IF WS-VALID-RC = ZERO
                CALL 'PAYCALC' USING EMP-REC PAY-RESULT
                CALL 'PAYRPT'  USING PAY-RESULT
            ELSE
                PERFORM WRITE-REJECT-REPORT
            END-IF
        END-IF
    END-PERFORM
    PERFORM CLOSE-FILES
    GOBACK.

This is only a sketch, but the shape is common. The main program reads the records and makes the top-level decisions. The called programs handle smaller pieces of the rule.

What belongs in a subprogram?

A subprogram is useful when the same rule is called from more than one place or when the rule is large enough to make the main program hard to read. Examples include tax calculation, interest calculation, address formatting, date validation, and report line building.

Good subprogram candidates

  • A calculation used by more than one batch job.
  • A validation rule shared by online and batch paths.
  • A report formatting routine that keeps the main flow short.
  • A database access routine with a clear input and output area.

Weak subprogram candidates

  • A two-line paragraph that is used only once.
  • A routine that changes global state without clear comments or return codes.
  • A module that needs too many unrelated fields in the USING list.

Data passed between programs

COBOL programs usually pass data through the CALL ... USING phrase. The calling program and called program must agree on the layout of the fields. If one side changes a copybook and the other side is not recompiled, the application can produce wrong values without an obvious compile error.

CALL 'PAYCALC' USING EMPLOYEE-RECORD
                     PAYROLL-RESULT
                     RETURN-AREA.

Keep the interface boring. Use clear copybook names, put return codes in a known place, and avoid sending every field in the application when the module only needs three values.

Files, DB2, and reports

Most COBOL applications are built around records. A batch program may read a sequential input file, update a VSAM file, call Db2 through embedded SQL, and write a report to SYSOUT. The application design should show which program owns each file or table update.

For file-heavy programs, review COBOL file operation and COBOL file I/O mode. Those topics explain why INPUT, OUTPUT, I-O, and EXTEND modes should match the way the application uses the data set.

Batch application checklist

  • Name the main program and each called module in the design note.
  • List input files, output files, VSAM clusters, Db2 tables, and reports.
  • Document every CALL ... USING interface with copybook names.
  • Define return codes for validation, calculation, and file errors.
  • Make restart points clear when the job updates files or tables.
  • Check whether called programs retain WORKING-STORAGE between calls.

Common mistakes

Putting every rule in the main program

A 5,000-line main program is hard to test and harder to support at 2 AM. Move repeated calculations and shared validation into called modules when the interface is stable.

Creating too many tiny modules

The opposite problem is also real. If a program calls twenty tiny modules to process one record, the support path becomes noisy. Keep module boundaries tied to business rules, files, or reports.

Ignoring retained storage

A called program can keep values in WORKING-STORAGE across calls, depending on how it ends and how it is compiled. That can be useful for counters, but it can also create a defect when a field from the previous employee is reused by accident. See COBOL Working Storage vs Local Storage and COBOL ending and reentering for the related behavior.

How to explain a COBOL application in an interview

A clear interview answer is short and practical: a COBOL application is a group of programs and resources that complete one business process. The first program in the run unit is the main program. Other programs are subprograms called for validation, calculation, database access, or reporting. Data is commonly passed with CALL ... USING, and the application is usually scheduled through JCL.

You can then give one example: a payroll application reads employee input, validates the record, calculates net pay, writes an output file, and prints a control report. That answer is much stronger than saying only that an application is a collection of programs.

Related COBOL tutorials

FAQ

Is a COBOL application the same as a COBOL program?

No. A COBOL program is one compiled source member. A COBOL application usually contains several programs, files, reports, JCL steps, and sometimes Db2 or CICS resources.

What is the main program in COBOL?

The main program is the first COBOL program in a run unit. It is not marked by a special COBOL statement; the way the run starts decides the role.

Why do COBOL applications use subprograms?

Subprograms keep repeated validation, calculation, file access, or report logic in smaller modules. That makes the application easier to test and support when the interface is clear.

What should I check before changing a COBOL application?

Check the JCL, called programs, copybooks, files, Db2 tables, return codes, and restart rules. A small copybook or file-layout change can affect several programs in the same application.

References

Sunday, 11 August 2013

COBOL DATA Compiler Option: DATA(24), DATA(31), and 16 MB Storage

A COBOL batch program can run out of below-the-line storage long before the machine is short of memory. The DATA compiler option helps decide where some run-time data areas can be allocated: below the 16 MB line with DATA(24), or above it with DATA(31).
COBOL DATA compiler option showing DATA 24 and DATA 31 storage placement
DATA(31) is the normal choice for modern programs.

This article explains the DATA compiler option in simple terms for mainframe COBOL developers. It covers what DATA(24) and DATA(31) mean, when each setting is used, and what to check before changing an old compile option.

What the COBOL DATA Compiler Option Controls

The DATA option affects where storage is obtained for dynamic data areas in Enterprise COBOL for z/OS. IBM documents DATA(31) as the default. For reentrant programs, DATA works with the Language Environment HEAP run-time option to decide whether dynamic areas such as non-external WORKING-STORAGE and FD record areas can be placed above the 16 MB line.

The important point is addressability. A program using 31-bit addressing can address storage above the 16 MB line. An old AMODE 24 program cannot. That is why DATA(24) still appears in some old compile procedures.

DATA(31) in COBOL

DATA(31) allows eligible dynamic run-time storage to be allocated above the 16 MB line. IBM recommends DATA(31) when the program does not need to call and pass parameters to AMODE 24 subprograms. In practice, this is the normal setting for most current Enterprise COBOL applications.

Why DATA(31) Helps

Below-the-line storage is limited. If QSAM buffers, working areas, and record areas all compete for that space, a busy batch job can hit storage pressure. With DATA(31), a reentrant program can keep more eligible storage above the line, especially when the run uses HEAP(,,ANYWHERE).

//COBOL.SYSIN DD *
PROCESS RENT,DATA(31)
IDENTIFICATION DIVISION.
PROGRAM-ID. ACCTLOAD.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-ACCOUNT-AREA PIC X(4096).
/*

This does not automatically make a slow program fast. The main benefit is storage placement. It can reduce pressure below the 16 MB line when the program and run-time options are set up correctly.

DATA(24) in COBOL

DATA(24) places eligible dynamic areas below the 16 MB line. You normally use it when the COBOL program must pass data to a 24-bit subprogram that cannot address data above the line.

Typical DATA(24) Scenario

Suppose a new COBOL program calls an old assembler routine that is linked AMODE 24. If the COBOL program passes the address of a work area above the 16 MB line, the old routine may not be able to address it. In that case, the compile and link-edit settings need a careful compatibility review before the program is promoted.

       CALL "OLDASM24" USING WS-CONTROL-BLOCK.

If OLDASM24 can only use 24-bit addresses, the storage passed in WS-CONTROL-BLOCK must be reachable by that routine. That is the kind of case where DATA(24) can still be required.

DATA(24) vs DATA(31)

Setting What it means When to use it
DATA(31) Eligible dynamic storage can be obtained above the 16 MB line. Use for most modern Enterprise COBOL programs unless an AMODE 24 dependency requires below-the-line data.
DATA(24) Eligible dynamic storage is kept below the 16 MB line. Use when the program passes data to AMODE 24 code that cannot address above-the-line storage.

What DATA Does Not Control

DATA is easy to misunderstand because the name sounds broad. It does not control every COBOL data item in every situation. IBM notes that LOCAL-STORAGE is not affected by the DATA compiler option; the stack run-time option and program addressing mode matter there instead.

External data also has related addressability rules. If a program uses EXTERNAL items, old called modules, or mixed-language calls, review the compile options, link-edit attributes, and Language Environment run-time options together.

How DATA Works with RENT and HEAP

The DATA option is often discussed with RENT because reentrant programs can have different storage behavior from non-reentrant programs. IBM notes that for non-reentrant programs, the RMODE option determines where non-external data is allocated.

For a reentrant program, this combination is common in modern compile procedures:

PROCESS RENT,DATA(31)

At run time, HEAP(,,ANYWHERE) can allow non-external WORKING-STORAGE and non-external FD record areas to be allocated above the 16 MB line. This is useful for batch programs with many files, large record areas, or sizable work areas.

How to Check the DATA Option in a Compile Listing

The fastest way to confirm the active setting is to check the compiler listing. Enterprise COBOL listings show the compiler options used for the compile. Site defaults can also affect the final option set, so do not rely only on what appears in the source member.

PROCESS RENT,DATA(31),MAP,XREF

If the source does not specify DATA, check the compile JCL, cataloged procedure, compiler option file, and installation defaults. Many shops keep options in a compile PROC rather than in each COBOL source member.

Migration Checks Before Changing DATA

Changing DATA(24) to DATA(31) is usually a good cleanup target, but it should not be done blindly. Check the called modules first. The risky case is not a normal COBOL-to-COBOL call in a current environment; the risky case is old code that still expects below-the-line addresses.

Before Changing DATA(24) to DATA(31)

  • Check whether the program calls assembler, old COBOL, PL/I, C, or vendor modules.
  • Check the AMODE and RMODE of the load modules involved in the run unit.
  • Review parameters passed through CALL ... USING.
  • Run a compile listing with MAP if you need storage layout detail.
  • Test the largest realistic input, not only a tiny unit-test file.

Common Mistakes

Using DATA(24) Forever Because It Was Already There

Old compile options often survive because nobody wants to touch them. If the program has no AMODE 24 dependency, DATA(31) is usually the better setting because it can reduce pressure below the line.

Expecting DATA(31) to Fix CPU Time

DATA(31) is about storage addressability, not SQL access paths or loop design. For CPU and elapsed-time issues, check the related Mainframe Forum notes on COBOL performance tuning and COBOL performance.

Ignoring LOCAL-STORAGE

If the issue involves LOCAL-STORAGE, the DATA option may not be the setting you need to review. Read the related guide on COBOL Working Storage vs Local Storage.

Related COBOL Compiler Options

The DATA option is only one part of a compile standard. When tuning or modernizing COBOL compile procedures, also review COBOL RENT compiler option, COBOL TRUNC compiler option, COBOL NUMPROC compiler option, and COBOL program compilation process.

FAQ

What is the default DATA option in Enterprise COBOL?

IBM documents DATA(31) as the default for Enterprise COBOL. Site installation defaults can still matter, so check the compile listing for the option actually used.

When should I use DATA(24)?

Use DATA(24) when a program running in 31-bit mode must pass data to AMODE 24 code that cannot address storage above the 16 MB line.

Does DATA affect LOCAL-STORAGE?

No. IBM documents that LOCAL-STORAGE is not affected by the DATA compiler option. Stack settings and program addressing mode control that area.

Does DATA(31) improve COBOL performance?

Not directly. It can reduce below-the-line storage pressure, but it is not a CPU tuning switch. Treat it as a storage addressability option.

References

For exact syntax and current compiler behavior, use IBM documentation for the DATA compiler option, DATA(24) and DATA(31), and Enterprise COBOL compiler options.

Use DATA(31) by default for current programs, and keep DATA(24) only when a real below-the-line dependency proves it is needed.

New In-feed ads