Skip to content

Add Lab: Case Sensitive Nature of COBOL Conditions (Lab 9) #334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2773,6 +2773,77 @@ This exercise develops skills in COBOL conditional processing, program structure

**Need Help?** If you encounter difficulties, you can refer to the complete solution code `CBLC1.cobol` available in VS Code Zowe Explorer or find it on [GitHub](https://github.com/openmainframeproject/cobol-programming-course/tree/master/COBOL%20Programming%20Course%20%232%20-%20Learning%20COBOL/Labs/cbl) repository.

# Case Sensitive Nature of COBOL Conditions

COBOL syntax is not case-sensitive for keywords and identifiers, but string literal comparisons in conditional expressions ARE case-sensitive. This distinction between language syntax and data comparisons can lead to programming errors that cause issues when your program interacts with:

- **External input data**, such as text files or database records
- **Conditional expressions** that depend on exact string matches
- **Third-party systems** that expect a specific case format

## Why It Matters

The most dangerous aspect of case sensitivity errors is that they often go unnoticed during initial testing. Programs **compile successfully**, **run without errors**, but **produce incorrect results**. These kinds of "silent failures" can persist in production systems for long periods, potentially resulting in:

- Inaccurate or misleading reports
- Logic failures (e.g., skipping conditional branches)
- Reports that appear complete but miss values
- Data corruption or misrouting

### Real-World Example

Modern COBOL treats statements like:
`MOVE MY-NUMBER TO YOUR-NUMBER`
and
`Move my-Number to your-Number` as **equivalent** because keywords and identifiers are case-insensitive.

However, **COBOL conditions** are case-sensitive when checking **string values**:

`IF USA-STATE = 'new York'` = Fails, mismatch due to case

`IF USA-STATE = 'New York'` = Succeeds, case matches

The comparison **fails silently** COBOL won't throw an error, but the result won't be as expected.

## Lab

**Case Sensitivity in Data Comparison:**
Understand how case sensitivity in COBOL string comparisons can cause logical errors and learn to identify and fix these issues.

**Scenario:** You'll investigate why a program designed to count "New York" clients returns zero when New York clients actually exist in the input data file (id.DATA).

**Required Files:**

- `CBL006A.cobol` - COBOL program source
- `CBL006AJ.jcl` - JCL job to compile and execute
- `id.DATA` - Input data file

All files are available in your VS Code Zowe Explorer.

### Instructions

1. Open `CBL006A.cobol` from your VS Code Zowe Explorer.

This program reads account records and counts how many clients are from `"New York"`.

2. Submit the JCL job `CBL006AJ.jcl`. View the job output from the JOBS section.
- Confirm that no syntax or runtime errors occurred.
- Now carefully read the final line of the report. `New York Clients = 000`

![](Images/image071.png)

Ask yourself: *Is this the number of New York clients you expected?*

3. Based on your understanding, where do you think the bug lies?
- Consider the case format of both the **comparison string** and the **actual data** from the file (id.DATA).
4. Go and update the source code `CBL006A.cobol` .
- Modify the string literal in the IF condition to match the exact case format found in the data file
5. Save your changes to `CBL006A.cobol`
6. Recompile and resubmit the job `CBL006AJ.jcl`
7. Verify that the report now correctly shows: `New York Clients = 005`

![](Images/image072.png)

\newpage

# Arithmetic expressions
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
173 changes: 173 additions & 0 deletions COBOL Programming Course #2 - Learning COBOL/Labs/cbl/CBL006A.cobol
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
*-----------------------
IDENTIFICATION DIVISION.
*-----------------------
PROGRAM-ID. CBL006A
AUTHOR. Otto B. Boolean.
*--------------------
ENVIRONMENT DIVISION.
*--------------------
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PRINT-LINE ASSIGN TO PRTLINE.
SELECT ACCT-REC ASSIGN TO ACCTREC.
*-------------
DATA DIVISION.
*-------------
FILE SECTION.
FD PRINT-LINE RECORDING MODE F.
01 PRINT-REC.
05 ACCT-NO-O PIC X(8).
05 FILLER PIC X(02) VALUE SPACES.
05 LAST-NAME-O PIC X(20).
05 FILLER PIC X(02) VALUE SPACES.
05 ACCT-LIMIT-O PIC $$,$$$,$$9.99.
05 FILLER PIC X(02) VALUE SPACES.
05 ACCT-BALANCE-O PIC $$,$$$,$$9.99.
05 FILLER PIC X(02) VALUE SPACES.
*
FD ACCT-REC RECORDING MODE F.
01 ACCT-FIELDS.
05 ACCT-NO PIC X(8).
05 ACCT-LIMIT PIC S9(7)V99 COMP-3.
05 ACCT-BALANCE PIC S9(7)V99 COMP-3.
05 LAST-NAME PIC X(20).
05 FIRST-NAME PIC X(15).
05 CLIENT-ADDR.
10 STREET-ADDR PIC X(25).
10 CITY-COUNTY PIC X(20).
10 USA-STATE PIC X(15).
05 RESERVED PIC X(7).
05 COMMENTS PIC X(50).
*
WORKING-STORAGE SECTION.
01 FLAGS.
05 LASTREC PIC X VALUE SPACE.
*
* CHANGE 1: Modified variable structure to count New York clients
* Original counted Virginia clients - now counts New York clients
01 CLIENTS-PER-STATE.
05 FILLER PIC X(19) VALUE
'New York Clients = '.
05 NEWYORK-CLIENTS PIC 9(3) VALUE ZERO.
05 FILLER PIC X(59) VALUE SPACES.
*
01 HEADER-1.
05 FILLER PIC X(20) VALUE 'Financial Report for'.
05 FILLER PIC X(60) VALUE SPACES.
*
01 HEADER-2.
05 FILLER PIC X(05) VALUE 'Year '.
05 HDR-YR PIC 9(04).
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(06) VALUE 'Month '.
05 HDR-MO PIC X(02).
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(04) VALUE 'Day '.
05 HDR-DAY PIC X(02).
05 FILLER PIC X(56) VALUE SPACES.
*
01 HEADER-3.
05 FILLER PIC X(08) VALUE 'Account '.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(10) VALUE 'Last Name '.
05 FILLER PIC X(15) VALUE SPACES.
05 FILLER PIC X(06) VALUE 'Limit '.
05 FILLER PIC X(06) VALUE SPACES.
05 FILLER PIC X(08) VALUE 'Balance '.
05 FILLER PIC X(40) VALUE SPACES.
*
01 HEADER-4.
05 FILLER PIC X(08) VALUE '--------'.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(10) VALUE '----------'.
05 FILLER PIC X(15) VALUE SPACES.
05 FILLER PIC X(10) VALUE '----------'.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(13) VALUE '-------------'.
05 FILLER PIC X(40) VALUE SPACES.
*
01 WS-CURRENT-DATE-DATA.
05 WS-CURRENT-DATE.
10 WS-CURRENT-YEAR PIC 9(04).
10 WS-CURRENT-MONTH PIC 9(02).
10 WS-CURRENT-DAY PIC 9(02).
05 WS-CURRENT-TIME.
10 WS-CURRENT-HOUR PIC 9(02).
10 WS-CURRENT-MINUTE PIC 9(02).
10 WS-CURRENT-SECOND PIC 9(02).
10 WS-CURRENT-CENTISECOND PIC 9(02).
* This data layout is organized according to the ouput
* format of the FUNCTION CURRENT-DATE.
*
*------------------
PROCEDURE DIVISION.
*------------------
OPEN-FILES.
OPEN INPUT ACCT-REC.
OPEN OUTPUT PRINT-LINE.
*
WRITE-HEADERS.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-DATA.
* The CURRENT-DATE function returns an alphanumeric value
* that represents the calendar date and time of day
* provided by the system on which the function is
* evaluated.
MOVE WS-CURRENT-YEAR TO HDR-YR.
MOVE WS-CURRENT-MONTH TO HDR-MO.
MOVE WS-CURRENT-DAY TO HDR-DAY.
WRITE PRINT-REC FROM HEADER-1.
WRITE PRINT-REC FROM HEADER-2.
MOVE SPACES TO PRINT-REC.
WRITE PRINT-REC AFTER ADVANCING 1 LINES.
WRITE PRINT-REC FROM HEADER-3.
WRITE PRINT-REC FROM HEADER-4.
MOVE SPACES TO PRINT-REC.
*
READ-NEXT-RECORD.
PERFORM READ-RECORD
PERFORM UNTIL LASTREC = 'Y'
* CHANGE 2: Updated paragraph name to reflect New York processing
* Original was IS-STATE-VIRGINIA, now IS-STATE-NEWYORK
PERFORM IS-STATE-NEWYORK
PERFORM WRITE-RECORD
PERFORM READ-RECORD
END-PERFORM
.
*
CLOSE-STOP.
WRITE PRINT-REC FROM CLIENTS-PER-STATE.
CLOSE ACCT-REC.
CLOSE PRINT-LINE.
GOBACK.
*
READ-RECORD.
READ ACCT-REC
AT END MOVE 'Y' TO LASTREC
END-READ.
*
* CHANGE 3: Updated paragraph name and logic to check for New York
* Original paragraph: IS-STATE-VIRGINIA
* - Checked for 'Virginia' state
* - Added to VIRGINIA-CLIENTS counter
* Modified paragraph: IS-STATE-NEWYORK
* - Now checks for 'New York' state
* - Adds to NEWYORK-CLIENTS counter

IS-STATE-NEWYORK.
IF USA-STATE = 'new York' THEN
ADD 1 TO NEWYORK-CLIENTS
END-IF.

* Boolean logic -- when the conditional expression
* USA-STATE = 'New York' is true, the program
* counts one more client from New York
* Note -- the inclusion of the word THEN is optional
* END-IF -- explicitly terminates the IF statement
*
WRITE-RECORD.
MOVE ACCT-NO TO ACCT-NO-O.
MOVE ACCT-LIMIT TO ACCT-LIMIT-O.
MOVE ACCT-BALANCE TO ACCT-BALANCE-O.
MOVE LAST-NAME TO LAST-NAME-O.
WRITE PRINT-REC.
*
21 changes: 21 additions & 0 deletions COBOL Programming Course #2 - Learning COBOL/Labs/jcl/CBL006AJ.jcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//CBL006AJ JOB 1,NOTIFY=&SYSUID
//***************************************************/
//* Copyright Contributors to the COBOL Programming Course
//* SPDX-License-Identifier: CC-BY-4.0
//***************************************************/
//COBRUN EXEC IGYWCL
//COBOL.SYSIN DD DSN=&SYSUID..CBL(CBL006A),DISP=SHR
//LKED.SYSLMOD DD DSN=&SYSUID..LOAD(CBL006A),DISP=SHR
//***************************************************/
// IF RC = 0 THEN
//***************************************************/
//RUN EXEC PGM=CBL006A
//STEPLIB DD DSN=&SYSUID..LOAD,DISP=SHR
//ACCTREC DD DSN=&SYSUID..DATA,DISP=SHR
//PRTLINE DD SYSOUT=*,OUTLIM=15000
//SYSOUT DD SYSOUT=*,OUTLIM=15000
//CEEDUMP DD DUMMY
//SYSUDUMP DD DUMMY
//***************************************************/
// ELSE
// ENDIF