COBOL Programming Course 2 Learning COBOL
COBOL Programming Course 2 Learning COBOL
Learning COBOL
Version 3.1.0
1
Copyright
COBOL Programming Course is licensed under Creative Commons Attribution 4.0 International. To view a
copy of this license, visit https://creativecommons.org/licenses/by/4.0.
2
Preface
Abstract
One computer programming language was designed specifically for business, Common Business-Oriented
Language, COBOL. Today COBOL remains as relevant as ever, handling $3 trillion in commerce every day.
This publication is aimed at beginners looking to build a working understanding of COBOL programming.
It describes how to work with COBOL using modern tools including Visual Studio Code with Zowe and Z
Open Editor extensions. It describes how to write, test, execute, and debug COBOL programs.
Authors
Michael Bauer is a development leader for the Open Mainframe value stream at Broadcom and is a squad
lead for the Zowe open source initiative. Zowe, a popular framework of modern interfaces for z/OS, opens
the mainframe to DevOps tools and practices. Mike leads the Command Line Interface (CLI) squad, which
created and recently spun-off the successful Zowe Explorer extension for Visual Studio Code. A frequent
speaker and blogger, Mike runs interactive workshops around the world for those interested in incorporating
mainframe in their enterprise DevOps initiatives.
Ahmed Eid is a computer engineering student from Egypt. He was a mentee for the Open Mainframe
Project 2021 Summer Mentorship under the COBOL Programming Course, helping to improve the content
of the course.
Zeibura Kathau is a technical writer for the Mainframe DevOps value stream at Broadcom. He works on
the open-source projects Che4z and Code4z, which are IDE extension packages for mainframe developers. He
has 8 years of experience in the Information Technology field.
Makenzie Manna is an IBM Redbooks Project Leader in the United States. She has 3 years of experience
in the Computer Science Software Development field. She holds a Master’s degree in Computer Science
Software Development from Marist College. Her areas of expertise include mathematics, IBM Z and cloud
computing.
Paul Newton is a Consulting IT Specialist in the United States. He has 40 years of experience in the
Information Technology field. He holds a degree in Information Systems from the University of Arizona. His
areas of expertise include IBM Z, z/OS, and LinuxONE. He has written extensively on implementation of
z/OS based technology.
Jonathan Sayles is a technical educator at IBM, where he conducts presentations, seminars and training
courses, as well as producing educational materials. His more than 40 years in the IT education and computer
industries encompass work within both academic and corporate development organizations. He has also
been engaged as a software developer/designer/consultant, educator, and author, with a focus on relational
database, IDE, and object technologies. In addition to authoring/publishing 16 books, Jon has written and
published more than 150 articles in technical journals, and served as technical editor for several IT magazines.
He is also co-author of IBM Redbook publications Transitioning: Informix 4GL to Enterprise Generation
Language (EGL), SG24-6673 and z/OS Traditional Application Maintenance and Support, SG24-7868.
Hartanto Ario Widjaya is a computer science student from Singapore Management University. He was a
mentee for the Open Mainframe Project 2021 Summer Mentorship under the COBOL Programming Course,
helping to improve the content of the course with various additions and assisting new learners to incorporate
COBOL as a part of their tech toolkit.
William Yates is a Software engineer working for IBM UK. For the majority of his career he has working
on the CICS TS product mainly as a software tester and now as Test Architect. He has delivered technical
content for many Redbooks, video courses and at conferences around the world. He is also one of the leaders
of the Galasa project, building an open source integration test framework for hybrid cloud applications
available at https://galasa.dev.
3
Acknowledgements
Special thanks to the following people for participating in the residency to shape the content in this publication.
• Dr. Tak Auyeung, Professor, American River College
• Jeffrey Bisti, Z Ecosystem Architect, IBM
• Ilicena Elliott, IT Specialist II, Employment Development Department
• Martin Keen, Technical Content Services, IBM
• Sudharsana Srinivasan, z Influencer Ecosystem Program Coordinator, IBM
• Suzy Wong, Information Technology Specialist, DMV
•
Left-to-right: Ilicena, Suzy, Makenzie, Martin, Paul, and Tak
4
Contents
1 Why COBOL? 9
1.1 What is COBOL? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2 How is COBOL being used today? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3 What insights does the survey conducted by Open Mainframe Project’s COBOL Working
Group provide? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.4 Why should I care about COBOL? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2 Basic COBOL 11
2.1 COBOL characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.1.1 Enterprise COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.1.2 Chapter objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2 What must a novice COBOL programmer know to be an experienced COBOL programmer? 12
2.2.1 What are the coding rules and the reference format? . . . . . . . . . . . . . . . . . . . 12
2.2.2 What is the structure of COBOL? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.3 What are COBOL reserved words? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.4 What is a COBOL statement? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.5 What is the meaning of a scope terminator? . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.6 What is a COBOL sentence? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.7 What is a COBOL paragraph? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.8 What is a COBOL section? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.9 How to run a COBOL program on z/OS? . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3 COBOL Divisions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.1 COBOL Divisions structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3.2 What are the four Divisions of COBOL? . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4 PROCEDURE DIVISION explained . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.5 Additional information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.1 Professional manuals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.2 Learn more about recent COBOL advancements . . . . . . . . . . . . . . . . . . . . . 16
2.6 Lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.7 Lab - Zowe CLI & Automation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.7.1 Zowe CLI - Interactive Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.7.2 Zowe CLI - Programmatic Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3 Data division 37
3.1 Variables / Data-items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.1.1 Variable / Data-item name restrictions and data types . . . . . . . . . . . . . . . . . . 37
3.2 PICTURE clause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.1 PIC clause symbols and data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.2 Coding COBOL variable / data-item names . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.3 PICTURE clause character-string representation . . . . . . . . . . . . . . . . . . . . . 38
3.3 Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.3.1 Figurative constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.3.2 Data relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.3.3 Levels of data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.4 MOVE and COMPUTE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.5 Lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4 Table handling 45
4.1 Defining a table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.2 Referring to an item in a table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.2.1 Subscripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.2.2 Indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
4.3 Loading a table with data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5
4.3.1 Loading a table dynamically . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.3.2 REDEFINES a hard-coded values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.3.3 INITIALIZE a table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.3.4 Assigning values using VALUE clause . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.4 Variable-length tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.5 Searching a table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.5.1 Serial search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.5.2 Binary search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4.6 Lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5 File handling 51
5.1 COBOL code used for sequential file handling . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.1.1 COBOL inputs and outputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.1.2 FILE-CONTROL paragraph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.1.3 COBOL external data source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.1.4 Data sets, records, and fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.1.5 Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.1.6 ASSIGN clause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.2 PROCEDURE DIVISION sequential file handling . . . . . . . . . . . . . . . . . . . . . . . . 55
5.2.1 Open input and output for read and write . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.2.2 Close input and output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.3 COBOL programming techniques to read and write records sequentially . . . . . . . . . . . . 56
5.3.1 READ-NEXT-RECORD paragraph execution . . . . . . . . . . . . . . . . . . . . . . . 57
5.3.2 READ-RECORD paragraph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.3.3 WRITE-RECORD paragraph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.3.4 Iterative processing of READ-NEXT-RECORD paragraph . . . . . . . . . . . . . . . 58
5.4 Lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6 Program structure 63
6.1 Styles of programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.1.1 What is structured programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.1.2 What is Object Orientated Programming . . . . . . . . . . . . . . . . . . . . . . . . . 64
6.1.3 COBOL programming style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
6.2 Structure of the Procedure Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
6.2.1 Program control and flow through a basic program . . . . . . . . . . . . . . . . . . . . 64
6.2.2 Inline and out of line perform statements . . . . . . . . . . . . . . . . . . . . . . . . . 65
6.2.3 Using performs to code a loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
6.2.4 Learning bad behavior using the GO TO keyword . . . . . . . . . . . . . . . . . . . . 66
6.3 Paragraphs as blocks of code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
6.3.1 Designing the content of a paragraph . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
6.3.2 Order and naming of paragraphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
6.4 Program control with paragraphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.4.1 PERFORM TIMES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
6.4.2 PERFORM THROUGH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
6.4.3 PERFORM UNTIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
6.4.4 PERFORM VARYING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
6.5 Using subprograms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.5.1 Specifying the target program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.5.2 Specifying program variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.5.3 Specifying the return value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6.6 Using copybooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.8 Lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6
7 File output 75
7.1 Review of COBOL write output process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
7.1.1 ENVIRONMENT DIVISION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
7.2 FILE DESCRIPTOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
7.2.1 FILLER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
7.3 Report and column headers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
7.3.1 HEADER-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
7.4 PROCEDURE DIVISION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
7.4.1 MOVE sentences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
7.4.2 PRINT-REC FROM sentences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
7.5 Lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
8 Conditional expressions 83
8.1 Boolean logic, operators, operands, and identifiers . . . . . . . . . . . . . . . . . . . . . . . . 83
8.1.1 COBOL conditional expressions and operators . . . . . . . . . . . . . . . . . . . . . . 83
8.1.2 Examples of conditional expressions using Boolean operators . . . . . . . . . . . . . . 85
8.2 Conditional expression reserved words and terminology . . . . . . . . . . . . . . . . . . . . . . 85
8.2.1 IF, EVALUATE, PERFORM and SEARCH . . . . . . . . . . . . . . . . . . . . . . . . 85
8.2.2 Conditional states . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
8.2.3 Conditional names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
8.3 Conditional operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
8.4 Conditional expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
8.4.1 IF ELSE (THEN) statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
8.4.2 EVALUATE statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
8.4.3 PERFORM statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
8.4.4 SEARCH statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
8.5 Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
8.5.1 Relation conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
8.5.2 Class conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
8.5.3 Sign conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
8.6 Lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
9 Arithmetic expressions 92
9.1 What is an arithmetic expression? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
9.1.1 Arithmetic operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
9.1.2 Arithmetic statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
9.2 Arithmetic expression precedence rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
9.2.1 Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
9.3 Arithmetic expression limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
9.4 Arithmetic statement operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
9.4.1 Size of operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
9.5 Examples of COBOL arithmetic statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
9.6 Lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
7
11.2 Intrinsic functions in Enterprise COBOL for z/OS V6.4 . . . . . . . . . . . . . . . . . . . . . 104
11.2.1 Mathematical example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
11.2.2 Statistical example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
11.2.3 Date/time example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
11.2.4 Financial example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
11.2.5 Character-handling example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
11.3 Use of intrinsic functions with reference modifiers . . . . . . . . . . . . . . . . . . . . . . . . . 106
11.4 Lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8
1 Why COBOL?
This chapter introduces COBOL, specifically regarding its use in enterprise systems.
• What is COBOL?
• How is COBOL being used today?
• What insights does the survey conducted by Open Mainframe Project’s COBOL Working
Group provide?
• Why should I care about COBOL?
1.3 What insights does the survey conducted by Open Mainframe Project’s
COBOL Working Group provide?
Highlights from the survey conducted by the Open Mainframe Project’s COBOL Working Group in 2021
shed further light on the use of COBOL in today’s era:
9
1. Over 250 billion lines of COBOL are currently in production worldwide, marking a notable
increase from previous estimates. This figure indicates that COBOL’s relevance is not waning; in fact,
it continues to play a vital role.
Industries with the greatest reliance on COBOL include Financial Services, Government, Software,
Logistics, Retail, and Manufacturing, among others.
2. The future of COBOL appears promising. Despite skeptics, 58% of respondents anticipate that
their COBOL applications will persist for at least the next five years. Financial services professionals,
in particular, exhibit even greater optimism, with over 55% expecting COBOL to endure indefinitely.
3. The challenge lies in the availability of COBOL skills. Interestingly, COBOL was originally
designed to be an accessible language that didn’t necessitate advanced computing expertise.However,
companies are worried about not having enough skilled COBOL programmers. Even though they can
train their own employees, this concern shows that COBOL is still important and worth investing in.
10
2 Basic COBOL
This chapter introduces the basics of COBOL syntax. It then demonstrates how to view and run a basic
COBOL program in VS Code.
• COBOL characteristics
– Enterprise COBOL
– Chapter objectives
• What must a novice COBOL programmer know to be an experienced COBOL program-
mer?
– What are the coding rules and the reference format?
– What is the structure of COBOL?
– What are COBOL reserved words?
– What is a COBOL statement?
– What is the meaning of a scope terminator?
– What is a COBOL sentence?
– What is a COBOL paragraph?
– What is a COBOL section?
– How to run a COBOL program on z/OS?
• COBOL Divisions
– COBOL Divisions structure
– What are the four Divisions of COBOL?
• PROCEDURE DIVISION explained
• Additional information
– Professional manuals
– Learn more about recent COBOL advancements
• Lab
• Lab - Zowe CLI & Automation
– Zowe CLI - Interactive Usage
– Zowe CLI - Programmatic Usage
11
2.1.2 Chapter objectives
The object of the chapter is to expose the reader to COBOL terminology, coding rules, and syntax while the
remaining chapters include greater detail with labs for practicing what is introduced in this chapter.
2.2.1 What are the coding rules and the reference format?
COBOL source code is column-dependent, meaning column rules are strictly enforced. Each COBOL source
code line has five areas, where each of these areas has a beginning and ending column.
COBOL source text must be written in COBOL reference format. Reference format consists of the areas
depicted in Figure 1. in a 72-character line.
12
2.2.1.4 Area B (columns 12 - 72)
• Certain items must begin in Area B, they are:
– Entries, sentences, statements, and clauses
– Continuation lines
• Column 12 is referred to as the B Margin
13
2.2.6 What is a COBOL sentence?
A COBOL “Sentence” is one or more “Statements” followed by a period (.), where the period serves as a
scope terminator.
14
2.3.1 COBOL Divisions structure
Divisions are subdivided into Sections.
Sections are subdivided into Paragraphs.
Paragraphs are subdivided into Sentences.
Sentences consist of Statements.
Statements begin with COBOL reserved words and can be subdivided into “Phrases”
2.3.2.3 DATA DIVISION The DATA DIVISION is where characteristics of data are defined in one of
the following sections:
• FILE SECTION:
Defines data used in input-output operations.
• LINKAGE SECTION:
Describes data from another program. When defining data developed for internal processing.
• WORKING-STORAGE SECTION:
Storage allocated and remaining for the life of the program.
• LOCAL-STORAGE SECTION:
Storage is allocated each time a program is called and de-allocated when the program ends.
15
• Sentence - A series of one or more COBOL statements ending with a period.
• Statement - An action to be taken by the program, such as adding two numbers.
• Phrase - A small part of a statement (i.e. subdivision), analogous to an English adjective or preposition
2.6 Lab
In this lab exercise, you will connect to an IBM Z system, view a simple COBOL hello world program in
VS Code, submit JCL to compile the COBOL program, and view the output. Refer to “Installation of VS
Code and extensions” to configure VS Code if you have not already done so. You can either use IBM Z Open
Editor and Zowe Explorer, or Code4z.
16
1. The lab assumes installation of VS Code with either IBM Z Open Editor and Zowe Explorer extensions,
as shown in Figure 2a, or the Code4z extension pack, as shown in Figure 2b.
Click the Extensions icon. If you installed IBM Z Open Editor and Zowe Explorer, the list should
include:
1. IBM Z Open Editor
2. Zowe Explorer
Figure 2a. The IBM Z Open Editor and Zowe Explorer VS Code extensions
If you installed Code4z, the list should include:
1. COBOL Language Support
2. Zowe Explorer
3. Explorer for Endevor
4. HLASM Language Support
5. Debugger for Mainframe
6. COBOL Control Flow
7. Abend Analyzer for Mainframe
8. Data Editor for Mainframe
In these exercises, you will only use the COBOL Language Support and Zowe Explorer extensions.
17
Figure 3. Zowe Explorer icon
3. In order to connect to the lab system, get your team configuration zip file and extract it. You can
obtain the team configuration zip file from the Releases section of the course’s GitHub repository.
18
Figure 5. Inside the Team configuration file
5. Now back on your VS Code window, select the Explorer tab, and press the “Open folder” button in the
left bar.
19
Figure 7a. Select the team Configuration folder
If you are prompted to trust the authors of the files in the folder as shown in Figure 7b, select Yes, I
trust the authors.
20
Figure 8a. LearnCOBOL Connection
If the connection does not appear, hover to the far right of the Data Sets line and press the + icon.
Afterward, select the LearnCOBOL connection as shown in Figure 8b.
21
Figure 9. Pressing the LearnCOBOL Connection
9. The connection prompts for a username as shown in Figure 10.
22
Figure 12. Password prompt
12. Enter your assigned password as shown in Figure 13.
23
Figure 16. Entered filter name
16. A list of data set names beginning with your username will appear as shown in Figure 17.
24
Figure 18. <USERNAME>.CBL
18. Expand <USERNAME>.JCL to view JCL members and select member HELLO which is the JCL used to
compile and execute a simple ‘Hello World!’ COBOL source code as shown in Figure 19.
25
Figure 19. <USERNAME>.JCL
19. Right-click on JCL member HELLO. A section box appears. Select Submit Job for the system to
process HELLO JCL as shown in Figure 20. The submitted JCL job compiles the COBOL HELLO
source code, then executes the COBOL HELLO program.
26
Figure 20. Submit Job
20. Observe the ‘Jobs’ section in Zowe Explorer as shown in Figure 21.
27
in Figure 24. Observe the Indicator Area in column 7, A Area beginning in column 8, and B Area
beginning in column 12. Also, observe the period (.) scope terminators in the COBOL source.
28
Figure 25. COBOL program execution
25. Do note that you will need to open the LearnCOBOL folder every time you connect to the system,
repeating step 5 to 7. To enable your connection profile to be accessible anywhere on your machine,
you will need to move your configuration files (i.e. zowe.config.json and zowe.schema.json) from
the LearnCOBOL folder to the Zowe global location. By default this is C:\Users\%USERNAME%\.zowe
for Windows or ~/.zowe for Linux and macOS.
26. The following URL is another excellent document describing the above VS Code and Zowe Explorer
details with examples: https://marketplace.visualstudio.com/items?itemName=Zowe.vscode-extension-
for-zowe
29
2.7.1 Zowe CLI - Interactive Usage
In this section, we will use the Zowe CLI interactively to view data set members, submit jobs, and review
spool output.
1. Within VS Code, open the integrated terminal (Terminal -> New Terminal). In the terminal, issue
zowe --version to confirm the Zowe CLI is installed as depicted in the following figure. If it is not
installed, please refer to the section on the “Installation of Zowe CLI and Plug-ins.” Also, notice that
the default shell selected is cmd. I would recommend selecting the default shell as either bash or cmd
for this lab.
30
Figure 27. List available team config connections
3. Confirm you can connect to z/OSMF by issuing the following command:
zowe zosmf check status
4. List data sets under your ID by issuing a command similar to (see sample output in the following
figure):
zowe files list ds " Z99998 .*"
You can also list all members in a partitioned data set by issuing a command similar to (see sample
output in the following figure):
zowe files list am " Z99998 . CBL "
31
Figure 28. zowe files list ds and am commands
5. Next, we will download our COBOL and JCL data set members to our local machine. From the
terminal, issue commands similar to:
zowe files download am " Z99998 . CBL " -e ". cbl "
zowe files download am " Z99998 . JCL " -e ". jcl "
Figure 29. Download and view data set members using the CLI
6. Next, we will submit the job in member Z99998.JCL(HELLO). To submit the job, wait for it to complete,
and view all spool content, issue:
32
zowe jobs submit ds " Z99998 . JCL ( HELLO ) " -- vasc
We could also perform this step in piecemeal to get the output from a specific spool file. See the next
figure for an example of the upcoming commands. To submit the job and wait for it to enter OUTPUT
status, issue:
zowe jobs submit ds " Z99998 . JCL ( HELLO ) " -- wfo
where JOB04064 and 105 are obtained from the previous commands.
Figure 30. Submit a job, wait for it to complete, then list spool files for the job, and view a specific
spool file
If desired, you can also easily submit a job, wait for it to complete, and download the spool content
using the following command (see the following figure for the completed state):
zowe jobs submit ds " Z99998 . JCL ( HELLO ) " -d .
33
Figure 31. Submit a job, wait for it to complete, download and view spool files
The Zowe CLI was built with scripting in mind. For example, you can use the --rfj flag to receive
output in JSON format for easy parsing. See the next figure for an example.
Figure 32. The --rfj flag allows for easy programmatic usage
34
Figure 33. Use of npm init to create package.json for the project
2. Now that we have our package.json simply replace the test script with a clg script that runs the
following zowe command (replace Z99998 with your high-level qualifier):
zowe jobs submit ds ' Z99998 . JCL ( HELLO ) ' -d .
You can name the script whatever you want. I only suggested clg because the CLG in the IGYWCLG proc
(which is what the JCL leverages) stands for compile, link, go. Now, simply issue npm run clg in your
terminal to leverage the automation to compile, link, and run the COBOL program and download the
output for review. An example of the completed package.json and command execution are shown in
the following figure.
35
Figure 34. Final package.json and npm run clg execution
3. If you prefer a graphical trigger, you can leverage VS Code as shown in the following figure. Essentially,
the CLI enables you to quickly build your own buttons for your custom z/OS tasks. You could also
invoke a script rather than a single command to accommodate more complex scenarios.
36
3 Data division
Understanding COBOL variables and program processing of variables are essential to effectively learning the
COBOL language. An experienced COBOL programmer must master the characteristics of COBOL variables
and the program processing using the variables introduced in this chapter. The objective is to introduce the
reader to the basics of COBOL variables while exposing the reader to the many advanced COBOL variable
options.
Following this chapter is a lab available to compile and execute the COBOL source code provided later in the
chapter. Following the successful compile and execution of one provided program, a second provided COBOL
program with a minor change is available to compile. The second program has an embedded error and on
compile will fail. The failed compilation is an opportunity to identify the error associated with the significance
of PICTURE clause data types associated with the operation of the COMPUTE statement (discussed in this
chapter) and how to solve the error.
• Variables / Data-items
– Variable / Data-item name restrictions and data types
• PICTURE clause
– PIC clause symbols and data types
– Coding COBOL variable / data-item names
– PICTURE clause character-string representation
• Literals
– Figurative constants
– Data relationships
– Levels of data
• MOVE and COMPUTE
• Lab
37
When COBOL source code is compiled into an executable program, the COBOL compiler is expecting a
named COBOL variable to possess attributes such as length and data type. During program execution, the
variable represents a defined area of processing memory where the memory location has a maximum length
and designated data type.
A list of the most common COBOL data types are:
• Numeric (0-9)
• Alphabetic (A-Z), (a-z), or a space
• Alphanumeric Numeric and Alphabetic Combination
38
• PIC clause for a value such as $1,123.45 is coded as follows:
PIC $9,999V99
3.3 Literals
A COBOL literal is a constant data value, meaning the value will not change like a variable can. The
COBOL statement, DISPLAY "HELLO WORLD!", is a COBOL reserved word, DISPLAY, followed by a literal,
HELLO WORLD!
3.3.2.1 Level numbers A structured level number hierarchic relationship is available to all DATA
DIVISION sections. Figure 1. shows the level number hierarchic relationship with programmer chosen level
numbers, variable names and PIC clauses in the File Section where “01 PRINT-REC” references the following
“05”-level group of variables and the “01 ACCT-FIELDS” references the following “05”-level group of variables.
Observe 05-level CLIENT-ADDR is further subdivided into several 10-level names. COBOL code referencing
the name CLIENT-ADDR includes the 10-level names.
39
40
Figure 1. Level number hierarchic relationship
41
Figure 2. MOVE and COMPUTE example
42
3.5 Lab
Note: It may take a few seconds to load in all segments of this lab. If files are not loading, hit the refresh
button on the list that appears when hovering over the section bar.
1. View the PAYROL00 COBOL source code member in the ‘id’.CBL data set.
2. Submit the JCL member, PAYROL00, from the id.JCL, where id is your id, dropdown. This is where
id.JCL(PAYROL00) compiles and successfully executes the PAYROL00. program.
Note: If you receive this error message after submitting the job:
That is because you submitted the job from the .CBL data set and not the .JCL data set.
3. View both compile and execution of PAYROL00 job output, referenced in Figure 4.
43
Figure 4. PAYROL00 output
4. Next, view PAYROL0X COBOL source code member in id.CBL data set.
5. View and submit the JCL member, PAYROL0X, from the id.JCL dropdown. This is where
id.JCL(PAYROL0X) compiles and executes the PAYROL0X program.
6. View the compile of PAYROLL0X job output, notice there is no execution output.
Do you notice a difference between this compile and the previous job compile shown in Figure 5. ?
44
4 Table handling
This section introduces the concept of tables, which are a collection of data items that have the same
description. The subordinate items are called table elements. A table is the COBOL equivalent of arrays.
The objective of this chapter is to provide information for the reader to be able to handle tables inside
COBOL programs.
In the example above, TABLE-NAME is the name of the group item. The table also contains a subordinate
item called SUBORDINATE-NAME which we are repeating n times. Each SUBORDINATE-ITEM has 2
elementary items, ELEMENT1 and ELEMENT2. In this case, we called SUBORDINATE-NAME as the
table element definition (since it includes the OCCURS clause). Note that the OCCURS clause cannot be
used in a level-01 description.
Alternatively, we can also make simpler tables:
01 TABLE-NAME .
05 SUBORDINATE OCCURS n TIMES PIC X (10) .
In this case, TABLE-NAME contains n SUBORDINATE items, each can contain up to 10 alphanumeric
characters.
We can also nest multiple OCCURS elements to create a table of additional dimensions, up to a limit of
seven dimensions. Note the example below:
01 PROGRAM-DETAILS .
05 PROGRAM-DEGREE PIC X (32) .
05 COURSE-DETAILS OCCURS 10 TIMES .
10 COURSE-NAME PIC X (32) .
10 INSTRUCTOR-ID PIC 9(10) .
10 A SS IG NM EN T- DE TA IL S OCCURS 8 TIMES .
15 ASSIGNMENT-NAME PIC X (32) .
15 A S S I G M M E N T - W E I G H T A G E PIC 9(03) .
Here, we are defining a degree program that has 10 courses and each course will have 8 assignments. What if
we don’t know how many times a table element will occur? To solve that, we can use variable-length tables,
using the OCCURS DEPENDING ON (ODO) clause which we will be going into more detail in a later
section.
4.2.1 Subscripting
Subscripting is using the data name of the table element, along with its occurrence number (which is called a
subscript). The lowest possible subscript number is 1, which defines the first occurrence of a table element.
45
We can also use literal or data name as a subscript. Note that if you are using a data name, it must be an
elementary numeric integer.
01 TABLE-NAME .
05 TABLE-ELEMENT OCCURS 3 TIMES PIC X (03) VALUE " ABC " .
...
MOVE " DEF " TO TABLE-ELEMENT (2)
In the above example, the second TABLE-ELEMENT will contain “DEF” instead of “ABC”.
4.2.2 Indexing
Alternatively, we can create an index using the INDEXED BY phrase of the OCCURS clause. This index
is added to the address of the table to locate an item (as a displacement from the start of the table). For
example,
05 TABLE-ELEMENT OCCURS 10 TIMES INDEXED BY INX-A PIC X (03) .
Here, INX-A is an index name. The compiler will calculate the value in the index as the occurrence number
minus 1 multiplied by the length of the table element. So, for example, for the second occurrence of
TABLE-ELEMENT, the binary value contained in INX-A is (2-1) * 3, or 3.
If you happen to have another table with the same number of table elements of the same length, you can use
an index name as a reference for both tables.
We can also define an index data item using the USAGE IS INDEX clause. These index data items can be
used with any table. For example,
77 INX-B USAGE IS INDEX .
...
SET INX-A TO 10.
SET INX-B TO INX-A .
PERFORM VARYING INX-A FROM 1 BY 1 UNTIL INX-A > INX-B
DISPLAY TABLE-ELEMENT ( INX-A )
...
END-PERFORM .
The index name INX-A is used to traverse the TABLE-ELEMENT table, while INX-B is used to hold the
index of the last element of the table. By doing this, we minimize the calculation of offsets and no conversion
will be necessary for the UNTIL condition.
We can also increment or decrement an index name by an elementary integer data item. For example,
SET INX-A DOWN BY 3
The integer there represents the number of occurrences. So it will be converted to an index value first before
it adds or subtracts the index.
Since we are comparing physical displacements, we cannot use index data items as subscripts or indexes. We
can only directly use it in SEARCH and SET statements or in comparisons with indexes.
The following example shows how to calculate displacements to elements that are referenced with indexes.
Consider the following two-dimensional table, TABLE-2D:
01 TABLE-2D .
05 TABLE-ROW OCCURS 2 TIMES INDEXED BY INX-A .
10 TABLE-COL OCCURS 5 TIMES INDEXED BY INX-B PIC X (4) .
46
TABLE - COL ( INX - A + 2 , INXB - 1)
This will cause the computation of the displacement to the TABLE-COL element:
( contents of INX - A ) + (20 * 2) + ( contents of INX - B ) - (4 * 1)
The calculation is based on the length of the elements. Each occurrence of TABLE-ROW is 20 bytes in length
(5 * 4) and each occurrence of TABLE-COL is 4 bytes in length.
In this example above, we execute a paragraph that reads files, and then we will iterate through every line of
the file until the end, putting each value into the table.
Here, we are taking hard-coded values of spelled-out numbers from 1 to 5 and loading them to a table through
the use of a REDEFINES clause.
47
01 TABLE-ONE .
05 TABLE-ELEMENT OCCURS 10 TIMES .
10 NUMBER-CODE PIC 9(02) VALUE 10.
10 ITEM-ID PIC X (02) VALUE " R3 " .
Here we have a table that contains 10 elements, each with its own NUMBER-CODE (with a value of 10) and
ITEM-ID (with a value of “R3”).
We can move the value 3 to each of the elementary numeric data items and the value “X” into each of the
elementary alphanumeric data items in the table:
INITIALIZE TABLE-ONE REPLACING NUMERIC DATA BY 3.
INITIALIZE TABLE-ONE REPLACING ALPHANUMERIC DATA BY " X " .
After running the two INITIALIZE statements, NUMBER-CODE will contain the value of 3, while ITEM-ID
will contain the value of “X”.
In the above example, the alphanumeric group data item TABLE-TWO uses a VALUE clause which initializes
each of the four elements of TABLE-TWO-DATA. So after initialization, TABLE-TWO-DATA(1) will contain
the alphanumeric ‘1’, TABLE-TWO-DATA(2) will contain the alphanumeric ‘2’, and so on.
In the above example, X is the ODO subject and Y is the ODO object.
There are a couple of factors affecting the successful manipulation of variable-length records:
• Correct calculation of record lengths
Here, the length of the variable portion is the product of the object of the DEPENDING ON phrase and the
length of the subject of the OCCURS clause.
• Conformance of the data in the object of the OCCURS DEPENDING ON clause to its PICTURE
clause
We must ensure that the ODO object correctly specifies the number of occurrences of table elements, or the
program could terminate abnormally.
The following example shows how we can use an OCCURS DEPENDING ON clause:
WORKING-STORAGE SECTION .
01 MAIN-AREA .
03 REC-1 .
05 FIELD-1 PIC 9.
05 FIELD-2 OCCURS 1 TO 5 TIMES
DEPENDING ON FIELD-1 PIC X (05) .
48
01 REC-2 .
03 REC-2-DATA PIC X (50) .
If we are moving REC-1 to REC-2, the length of REC-1 will be determined immediately beforehand using the
current value of FIELD-1. If FIELD-1 doesn’t conform to its PICTURE clause, the result is unpredictable.
So, we need to ensure that the ODO object (FIELD-1) has the correct value before moving REC-1 to REC-2.
On the other hand, if we are moving to REC-1, the length is determined using the maximum number of
occurrences. However, if REC-1 is followed by a variably located group, the ODO object will be used in the
calculation of the actual length of REC-1. An example of such case is provided below:
01 MAIN-AREA .
03 REC-1 .
05 FIELD-1 PIC 9.
05 FIELD-3 PIC 9.
05 FIELD-2 OCCURS 1 TO 5 TIMES
DEPENDING ON FIELD-1 PIC X (05) .
03 REC-2 .
05 FIELD-4 OCCURS 1 TO 5 TIMES
DEPENDING ON FIELD-3 PIC X (05) .
So in the case above, the value of the ODO object must be set before using the group item as a receiving field.
The code above will search the list of names from an index of 1. If it found the content of PEOPLE-SEARCH-
DATA, it will DISPLAY “Found”, otherwise, it will DISPLAY “Not found”.
For a more complex use case, we can also use nested SEARCH statements. We will need to delimit each
nested SEARCH statement with END-SEARCH.
49
4.5.2 Binary search
To do a binary search, we can use a SEARCH ALL statement. We do not need to set the index, but it will
use the one associated with the OCCURS clause. To use the SEARCH ALL statement, the table must specify
the ASCENDING or DESCENDING KEY phrases of the OCCURS clause, or both, and it must be ordered
on the specified key.
Using the WHEN phrase, you can test any key that is named in the ASCENDING or DESCENDING KEY
phrases. The test must be an equal-to condition, and the WHEN phrase must specify either a key or a
condition-name associated with the key.
For example, assume that we have a list of names sorted in ascending order:
77 PE OPL E- SE AR CH -D AT A PIC X (20) .
01 P EO P L E- T A BL E - BI N A RY .
05 PEOPLE-NAME OCCURS 50 TIMES
ASCENDING KEY IS PEOPLE-NAME
INDEXED BY PL-IDX PIC X (20) .
...
PR OC ED UR E- DI VI SI ON .
...
SEARCH ALL PEOPLE-NAME
AT END DISPLAY " Not found "
WHEN PE OP LE -S EA RC H- DA TA = PEOPLE-NAME ( PL-IDX )
DISPLAY " Found " .
The code above will search the alphabetically sorted list of names. If it found the content of PEOPLE-
SEARCH-DATA, it will DISPLAY “Found”, otherwise, it will DISPLAY “Not found”.
4.6 Lab
Note: It may take a few seconds to load in all segments of this lab. If files are not loading, hit the refresh
button on the list that appears when hovering over the section bar.
1. View the SRCHSER COBOL source code member in the ‘id’.CBL data set.
2. Submit the JCL member, SRCHSERJ, from the id.JCL, where id is your id, dropdown. This is where
id.JCL(SRCHSERJ) compiles and successfully executes the SRCHSER program.
3. View both compile and execution of SRCHSERJ job output.
4. Next, view SRCHBIN COBOL source code member in id.CBL data set.
5. View and submit the JCL member, SRCHBINJ, from the id.JCL dropdown. This is where
id.JCL(SRCHBINJ) compiles and executes the SRCHBIN program.
6. View the compile and execution of SRCHBINJ job output.
7. Compare SRCHSER with SRCHBIN. Do you notice the differences?
a. Observe how the tables are defined.
b. Observe how the tables are loaded from the id.DATA data set.
c. Observe the SEARCH and SEARCH ALL statements.
50
5 File handling
The previous chapter and lab focused on variables and moving literals into variables, then writing variable
content using the COBOL DISPLAY statement. This section introduces reading records from files into
variables, moving the variables to output variables, and writing the output variables to a different file. A
simple COBOL program to read each record from a file and write each record to a different file is used to
illustrate the COBOL code necessary to read records from an input external data source and write records to
an output external data source.
An experienced COBOL programmer can answer the question, “How does an Enterprise COBOL program
read data from an input external data source and write data to an output external data source?” The
objective of this chapter is to provide enough comprehensive information for the reader to be able to answer
that question.
• COBOL code used for sequential file handling
– COBOL inputs and outputs
– FILE-CONTROL paragraph
– COBOL external data source
– Data sets, records, and fields
– Blocks
– ASSIGN clause
• PROCEDURE DIVISION sequential file handling
– Open input and output for read and write
– Close input and output
• COBOL programming techniques to read and write records sequentially
– READ-NEXT-RECORD paragraph execution
– READ-RECORD paragraph
– WRITE-RECORD paragraph
– Iterative processing of READ-NEXT-RECORD paragraph
• Lab
51
– WRITE FROM statement
Figure 1. FILE-CONTROL
While SELECT gives a name to an internal file and ASSIGN gives a name to the external dataset name,
a COBOL program needs more information about both. The COBOL compiler is given more information
about both in the DATA DIVISION, FILE SECTION.
The COBOL reserved word ‘FD’ is used to give the COBOL compiler more information about internal file
names in the FILE-SECTION. The code below the FD statement is the record layout. The record layout
consists of level numbers, variable names, data types, and lengths as shown in Figure 2.
52
Figure 2. FILE-SECTION
5.1.5 Blocks
Each record read by the program can result in disk storage access. A program typically reads 1 record at a
time in sequential order until all records are read. When a record is read, the record retrieved from disk is
stored in memory for program access. When each next record read requires the need to retrieve the record
from disk, system performance is impacted negatively. Records can be blocked where a block is a group
of records. The result is when the first record is read, then an entire block of records is read into memory
assuming the program will be reading the second, third, etc. records avoiding unnecessary disk retrievals and
negative system performance. The memory holding a record or block of records to be read by the program is
53
known as a buffer. COBOL BLOCK CONTAINS clause is available to specify the size of the block in the
buffer. Observe Figure 3.
54
JCL is a separate z/OS technical skill. The introduction to COBOL explains just enough about JCL to
understand how the COBOL internal file name locates the external sequential dataset name. To read more
on JCL, visit the IBM Knowledge Center:
https://www.ibm.com/docs/en/zos-basic-skills?topic=collection-basic-jcl-concepts
Figure 4. OPEN-FILES
55
Figure 5. CLOSE-STOP
56
Figure 6. Reading and writing records
Note: COBOL is English-like and COBOL reserved words are English-like. The programmer is free to
use English-like variable names to help remember the purpose of the variable names. The PROCEDURE
DIVISION structure is English-like. A paragraph contains one or more sentences. A sentence contains one or
more statements. The implicit scope terminator, a period (.), terminates a sentence or terminates several
consecutive statements which would be analogous to a compounded sentence where ‘and’ joins potentially
independent sentences together. ###
57
The PERFORM UNTIL through END-PERFORM, explicit scope terminator, is repeatedly executed until
the LASTREC variable contains Y. The first PERFORM READ-RECORD results in a branch to the
READ-RECORD paragraph. Observe #1 in Figure 7.
58
Figure 7. Iterative processing
5.4 Lab
The lab associated with this chapter demonstrates the ‘end-of-file’ COBOL coding technique for reading all
data records from a sequential file. If a step has an asterisk (*) next to it, it will have a hint associated at
the end of the lab content.
1. If not already, open VS Code and select Zowe Explorer from the left sidebar.
Note: If you are opening a new instance of VS Code (i.e. you closed out of it after the previous usage),
you may need to ‘Select a filter’ again. You can do so by selecting the search icon next to your named
connection in the DATA SETS section and then reselecting the filter previously used. It should be in the
listed filters after you have selected the search symbol.
2. View these COBOL source code members listed in the id.CBL data set:
59
• CBL0001
• CBL0002
3. View these three JCL members in the id.JCL data set:
• CBL0001J
• CBL0002J
• CBL0003J
Figure 8. Id.JCL(CBL0001J).jcl
4. Submit job, JCL(CBL0001J), within the DATA SET section.
5. View that job output using the JOBS section.
• COBRUN:SYSPRINT(101) - COBOL program compiler output
• RUN:PRTLINE(103) - COBOL program execution output, shown in Figure 9.
60
Figure 10. IGYPS2121-S message
8. Edit CBL(CBL0002):
• Determine the appropriate spelling of PRINT-REX, correct it within the source code, and save
the updated source code.
9. Re-submit job, JCL(CBL0002J), using the DATA SET section and view the output in the JOBS section.
• COBRUN:SYSPRINT(101) COBOL program compiler output
• RUN:PRTLINE(103) is the COBOL program execution output (if correction is successful)
10. Submit job, JCL(CBL0003J), using the DATA SET section.
11. View CBL0003J ABENDU4038 output, using the JOBS section:
• View the IGZ00355 abend message in RUN:SYSOUT(104) from the COBOL program execution
output.
• IGZ00355 reads, program is unable to open or close ACCTREC file name, shown in Figure 11. guiding
you to the root of the error.
61
Figure 12. RUN:PRTLINE(103) for JCL(CBL0003J)
Lab hints
13. The error is located on line 11, adjust ‘ACCTREX’ accordingly.
62
6 Program structure
In this chapter, we discuss the concept of structured programming and how it relates to COBOL. We highlight
the key techniques within the COBOL language that allow you to write good well-structured programs.
• Styles of programming
– What is structured programming
– What is Object Orientated Programming
– COBOL programming style
• Structure of the Procedure Division
– Program control and flow through a basic program
– Inline and out of line perform statements
– Using performs to code a loop
– Learning bad behavior using the GO TO keyword
• Paragraphs as blocks of code
– Designing the content of a paragraph
– Order and naming of paragraphs
• Program control with paragraphs
– PERFORM TIMES
– PERFORM THROUGH
– PERFORM UNTIL
– PERFORM VARYING
• Using subprograms
– Specifying the target program
– Specifying program variables
– Specifying the return value
• Using copybooks
• Summary
• Lab
63
Unstructured programming constructs, also known as spaghetti code, are concepts such as GOTO or JUMP
which allow the flow of execution to branch wildly around the source code. Such code like this is hard to
analyze and read. Although COBOL does contain these structures, it is important to use them sparingly and
not as the backbone of well-structured code.
Well-structured code is both easy to understand and to maintain. It is highly likely that at some point in
your career you will be required to read and work from someone else’s code, often a decade after it was
originally written. It would be extremely helpful to you if the original author structured their code well and
likewise if it is your code someone else is reading.
...
64
CLOSE PRINT-LINE .
STOP RUN .
PERFORM WRITE-NEW-RECORD .
PERFORM WRITE-NEW-RECORD .
PERFORM WRITE-NEW-RECORD .
PERFORM WRITE-NEW-RECORD .
PERFORM WRITE-NEW-RECORD .
PERFORM WRITE-NEW-RECORD .
PERFORM WRITE-NEW-RECORD .
PERFORM WRITE-NEW-RECORD .
PERFORM WRITE-NEW-RECORD .
PERFORM WRITE-NEW-RECORD .
CLOSE PRINT-LINE .
STOP RUN .
WRITE-NEW-RECORD .
ADD 1 TO COUNTER GIVING COUNTER
MOVE COUNTER TO MSG-TO-WRITE
WRITE PRINT-REC .
65
MOVE ' THE NUMBER IS : ' TO MSG-HEADER OF PRINT-REC .
CLOSE PRINT-LINE .
STOP RUN .
Example 5. GO TO example
If we were to compile and run the program, you would see that although the job ABENDS (abnormally ends)
with a 4038-abend code, it did execute some of the code and wrote the first two lines of the output. If you
were to look at the output in more detail, you would see a message like the following:
IGZ0037S The flow of control in program TOTEN1 proceeded beyond the last
line of the program .
66
As we can see, the use of GO TO causes a branch of execution that doesn’t return to the line of code that
issued it. Let’s demonstrate how messy this code can get:
0 01 FLAG PIC 9(1) VALUE 1.
67
period (.). A paragraph can contain one to many COBOL sentences and is terminated either by the start of
another paragraph or the physical end of the program.
Note: A paragraph can also be ended by END-PROGRAM, END-METHOD, END FACTORY OR END-
OBJECT. Most of these are used within Object Orientated COBOL which is not discussed here.
Considering that a program can be made up of multiple paragraphs and that the PERFORM keyword can
be used to call the paragraph, either conditionally or as part of a loop, it is easy to see that good paragraph
design really helps makes your COBOL more structured and readable.
68
PERFORM UNTIL LASTREC = 'Y '
PERFORM 5000- WRITE-RECORD
PERFORM 4000- READ-RECORD
END-PERFORM .
*
3000- CLOSE-STOP .
CLOSE ACCT-REC .
CLOSE PRINT-LINE .
STOP RUN .
*
4000- READ-RECORD .
READ ACCT-REC
AT END MOVE 'Y ' TO LASTREC
END-READ .
*
5000- WRITE-RECORD .
MOVE ACCT-N - 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 .
MOVE FIRST-NAME TO FIRST-NAME-O .
MOVE COMMENTS TO COMMENTS-O .
WRITE PRINT-REC .
69
6.4.1 PERFORM TIMES
Perhaps the simplest way of repeating a perform statement is to use the TIMES keyword to perform a
paragraph or sections of code a static number of times, shown in Example 10.
PERFORM 10 TIMES
MOVE FIELD-A TO FIELD-B
WRITE RECORD
END-PERFORM .
70
Example 13. PERFORM UNTIL
This would be equivalent to the Java code:
int counter = 0;
while ( counter != 10) {
counter ++;
System . out . println ( " The number is : " + counter ) ;
}
71
Example 19. Java extended loop
This is really, just two for loops nested within each other. This construct is very useful when iterating over
tables or nested record structures. As for each loop of the outer varying loop, the inner loop will be executed
five times. As mentioned previously, the test of the condition will be assumed by COBOL to be at the
beginning of the loop, however, it can be specified to be evaluated at the end of the loop by adding the phrase
WITH TEST AFTER to the initial perform sentence.
72
You might also see the phrase, BY VALUE, being used in a CALL sentence. BY VALUE is similar to BY
CONTENT, as a copy of the content of the variable is passed. The difference is that only a subset of COBOL
data types are supported and you can only specify elementary data items. This is because BY VALUE is
primarily used when COBOL is calling a program of another language (such as C).
73
6.7 Summary
In summary, this chapter should provide the necessary foundation to understand structured programming and
how it relates to COBOL and its importance to understanding and maintaining code. Many examples of how,
when, and why to implement key techniques have been provided and explained for further understanding.
You should be able to identify the basic differences between structured programming (COBOL) and OO
programming (Java). You should also understand the general concept of the best practices in the structure of
the Procedure Division with reference to the design and content of paragraphs, program control options, and
ways to call other programs within the same system.
6.8 Lab
This lab utilizes COBOL program CBL0033, located within your id.CBL data set, as well as JCL job
CBL0033J, located within your id.JCL data set. The JCL jobs are used to compile and execute the COBOL
programs, as discussed in previous chapters.
74
7 File output
Designing a structured layout that is easy to read and understand is required to format output. Designing a
structured layout involves column headings and variable alignment using spaces, numeric format, currency
format, etc. This chapter aims to explain this concept utilizing example COBOL code to design column
headings and align data names under such headings. At the end of the chapter, you are asked to complete a
lab that practices the implementation of the components covered.
A capability of COBOL data output formatting that is worth noting but not covered in this chapter is that
COBOL is a web-enabled computer language. COBOL includes an easy and quick transformation of existing
COBOL code to write JSON (JavaScript Object Notation) where the output is subsequently formatted for a
browser, a smartphone, etc. Frequently, the critical data accessed by a smartphone, such as a bank balance,
is stored and controlled by z/OS where a COBOL program is responsible for retrieving and returning the
bank balance to the smartphone.
• Review of COBOL write output process
– ENVIRONMENT DIVISION
• FILE DESCRIPTOR
– FILLER
• Report and column headers
– HEADER-2
• PROCEDURE DIVISION
– MOVE sentence
– PRINT-REC FROM sentences
• Lab
75
Figure 1. SELECT and ASSIGN
7.2.1 FILLER
Observe the data name FILLER. While most data fields have unique names, FILLER is a COBOL reserved
word data name, that is useful for output formatting. This is in part because FILLER allocates memory
space without the need for a name. Also, FILLER allocated memory has a defined length in the output line
and may contain spaces or any literal. Figure 2. shows multiple VALUE SPACES for FILLER. SPACES
create white space between data items in the output which is valuable in keeping the code readable. More
specifically in Figure 2. FILLER PIC X(02) VALUE SPACES, represents the output line containing two
spaces.
76
Figure 2. FILLER
77
– Examples:
∗ ‘Year’ followed by a variable name
∗ ‘Month’ followed by a variable name
∗ ‘Day’ followed by a variable name
• HEADER-3:
– Writes literals
– Examples:
∗ ‘Account’ followed by FILLER spacing
∗ ‘Last Name’ followed by FILLER spacing
∗ ‘Limit’ followed by FILLER spacing
∗ ‘Balance; followed by FILLER spacing
• HEADER-4:
– Writes dashes followed by FILLER spacing
78
Figure 3. Designed output structure layout
79
7.3.1 HEADER-2
HEADER-2 includes the year, month, day of the report together with FILLER area, creating blank spaces
between the year, month, and day, as you can see in Figure 3. Figure 4. is an example of the data name
layout used to store the values of CURRENT-DATE. The information COBOL provides in CURRENT-DATE
is used to populate the output file in HEADER-2.
80
Figure 5. Execution logic to write header layout structure
7.5 Lab
This lab utilizes two COBOL programs, CBL0004, and CBL0005, located within your id.CBL data set, as
well as two JCL jobs, CBL0004J and CBL0005J, located within your id.JCL data set. The JCL jobs are used
to compile and execute the COBOL programs, as discussed in previous chapters.
81
7.5.0.1 Using VS Code and Zowe Explorer
1. Submit job: CBL0004J
2. Observe the report written with headers like Figure 6. below.
82
8 Conditional expressions
This chapter dives into how programs make decisions based upon the programmer’s written logic. Specifically,
programs make these decisions within the PROCEDURE DIVISION of the source code. We will expand on
several topics regarding conditional expressions written in COBOL through useful explanations, examples,
and eventually practicing implementation through a lab.
• Boolean logic, operators, operands, and identifiers
– COBOL conditional expressions and operators
– Examples of conditional expressions using Boolean operators
• Conditional expression reserved words and terminology
– IF, EVALUATE, PERFORM and SEARCH
– Conditional states
– Conditional names
• Conditional operators
• Conditional expressions
– IF ELSE (THEN) statements
– EVALUATE statements
– PERFORM statements
– SEARCH statements
• Conditions
– Relation conditions
– Class conditions
– Sign conditions
• Lab
83
A list of COBOL Boolean relational operators for each of the common types of COBOL conditional expressions
is represented in Figures 1, 2, and 3 below.
84
8.1.2 Examples of conditional expressions using Boolean operators
A simple conditional expression can be written as:
IF 5 > 1 THEN DISPLAY '5 is greater than 1' ELSE DISPLAY '1 is greater than 5'.
Compounded conditional expressions are enclosed in parenthesis and their Boolean operators are:
AND
OR
The code snippet below demonstrates a compounded conditional expression using the AND Boolean operator.
IF (5 > 1 AND 1 > 2)THEN .... ELSE ....
This conditional expression evaluates to false because while 5 > 1 is true, 1 > 2 is false. The AND operation
requires both expressions to be true to return true for the compounded condition expression. Let’s show
another implementation, this time using the OR Boolean operator.
IF (5 > 1 OR 1 > 2)THEN .... ELSE ....
This conditional expression evaluates to true because while 1 > 2 is false, 5 > 1 is true. The OR operation
requires only one of the expressions to be true to return true for the entire compounded condition expression.
More conditional operators used for relation, class, and sign conditions are discussed further in the chapter.
85
....
....
PROCEDURE DIVISION .
....
....
MOVE 'AZ ' TO USA-STATE .
....
....
IF STATE DISPLAY ' The State is Texas '
ELSE DISPLAY ' The State is not Texas '
END-IF .
....
....
MOVE 'TX ' TO USA-STATE .
....
....
IF STATE DISPLAY ' The State is Texas '
ELSE DISPLAY ' The State is not Texas '
END-IF .
86
8.3 Conditional operators
Relational operators compare numeric, character string, or logical data. The result of the comparison, either
true (1) or false (0), can be used to make a decision regarding program flow. Table 1 displays a list of
relational operators, how they can be written, and their meaning.
87
EVALUATE FACIAL-EXP
WHEN ' HAPPY '
DISPLAY 'I am glad you are happy '
WHEN 'SAD '
DISPLAY ' What can I do to make you happy '
WHEN ' PERPLEXED '
DISPLAY ' Can you tell me what you are confused about '
WHEN ' EMOTIONLESS '
DISPLAY ' Do you approve or disapprove '
END-EVALUATE
88
WORKING-STORAGE SECTION .
01 FACIAL-EXP-TABLE REDEFINES FACIAL-EXP-LIST .
05 FACIAL-EXP PIC X (11) OCCURS n TIMES INDEXED BY INX-A .
88 HAPPY VALUE " HAPPY " .
....
....
PROCEDURE DIVISION .
....
....
SEARCH FACIAL-EXP
WHEN HAPPY ( INX-A ) DISPLAY 'I am glad you are happy '
END-SEARCH
8.5 Conditions
A conditional expression can be specified in either simple conditions or complex conditions. Both simple
and complex conditions can be enclosed within any number of paired parentheses; the parentheses, however,
do not change whether the condition is simple or complex. This section will cover three of the five simple
conditions:
• Relation
• Class
• Sign
89
• DBCS
– IS DBCS or IS NOT DBCS
– IS KANJI or IS NOT KANJI
8.6 Lab
This lab requires two COBOL programs, CBL0006 and CBL0007, and two respective JCL Jobs, CBL0006J
and CBL0007J, to compile and execute the COBOL programs. All of which are provided to you in your VS
Code - Zowe Explorer.
90
7. Go ahead and modify id.CBL(CBL0007) to correct the syntax error outlined by the IGYPS2113-E
message.*
8. Re-submit CBL0007J
9. Validate that the syntax error was corrected by getting an error-free output file.
91
9 Arithmetic expressions
This chapter aims to introduce the concept of implementing arithmetic expressions in COBOL programs.
We will review the basic concept of arithmetic expressions, operators, statements, limitations, statement
operands, as well as precedence of operation within the expressions. You will be able to follow along with a
comprehensive example exhibiting the usage of arithmetic expressions in a COBOL program that you have
seen in previous chapters and labs. Following the chapter is a lab to practice the implementation of what you
have learned.
• What is an arithmetic expression?
– Arithmetic operators
– Arithmetic statements
• Arithmetic expression precedence rules
– Parentheses
• Arithmetic expression limitations
• Arithmetic statement operands
– Size of operands
• Examples of COBOL arithmetic statements
• Lab
92
Binary operator Meaning Unary operator Meaning
- Subtraction - Multiplication by -1
Multiplication
/ Division
Exponentiation
9.2.1 Parentheses
Parentheses are used to denote modifications to the normal order of operations (precedence rules). An
arithmetic expression within the parentheses is evaluated first and the result is used in the rest of the
expression. When expressions are contained within nested parentheses, evaluation proceeds from the least
inclusive to the most inclusive set. That means you work from the innermost expression within parentheses
to the outermost. The precedence for how to solve an arithmetic expression in Enterprise COBOL with
parentheses is:
1. Parentheses (simplify the expression inside them)
2. Unary operator
3. Exponents
4. Multiplication and division (from left to right)
5. Addition and subtraction (from left to right)
Parentheses either eliminate ambiguities in logic where consecutive operations appear at the same hierarchic
level or modify the normal hierarchic sequence of execution when necessary. When the order of consecutive
93
operations at the same hierarchic level is not completely specified by parentheses, the order is from left to
right.
An arithmetic expression can begin only with a left parenthesis, a unary operator, or an operand (that is, an
identifier or a literal). It can end only with a right parenthesis or an operand. An arithmetic expression must
contain at least one reference to an identifier or a literal.
There must be a one-to-one correspondence between left and right parentheses in an arithmetic expression,
with each left parenthesis placed to the left of its corresponding right parenthesis. If the first operator in
an arithmetic expression is a unary operator, it must be immediately preceded by a left parenthesis if that
arithmetic expression immediately follows an identifier or another arithmetic expression.
94
ROUNDING and ON SIZE ERROR handling.
95
Figure 2. Number level data-items (2)
In Figure 3. the READ-NEXT-RECORD paragraph, located within the PROCEDURE DIVISION, includes
a PERFORM LIMIT-BALANCE-TOTAL statement. The result of this statement is to transfer control to
the LIMIT-BALANCE-TOTAL paragraph, located within the PROCEDURE DIVISION, to perform the
COMPUTE statements.
Figure 3. READ-NEXT-RECORD.
96
Figure 4. is an example of two COMPUTE statements in the paragraph, LIMIT-BALANCE-TOTAL. Notice
that the results of the COMPUTE statements are to add client ACCT-LIMIT to the current TLIMIT and
add client ACCT-BALANCE to TBALANCE totals each time the paragraph is executed, which is one time
for each client record read in our example.
Figure 5. WRITE-TLIMIT-TBALANCE
97
9.6 Lab
This lab requires two COBOL programs, CBL0008 and CBL0009, and two respective JCL Jobs, CBL0008J
and CBL0009J, to compile and execute the COBOL programs. All of which are provided to you in your VS
Code - Zowe Explorer.
98
Figure 7. IGYPS2121-S error message
7. Re-submit CBL0009J
8. Validate that the syntax error was corrected by getting an error-free output file like in Figure 8. The
correction should report written with trailers consisting of limit and balance totals, like Figure 6.
99
10 Data types
A COBOL programmer must be aware that the computer stored internal data representation and formatting
can differ, where the difference must be defined in the COBOL source code. Understanding the computer’s
internal data representation requires familiarity with binary, hexadecimal, ASCII, and EBCDIC. Packed-
Decimal is needed to explain COBOL Computational and Display data format. This chapter aims to
familiarize the reader with these different “types” of data representation.
• Data representation
– Numerical value representation
– Text representation
• COBOL DISPLAY vs COMPUTATIONAL
• Lab
10.1.1.1 COMP-1 This is also known as a single-precision floating-point number representation. Due to
the floating-point nature, a COMP-1 value can be very small and close to zero, or it can be very large (about
10 to the power of 38). However, a COMP-1 value has limited precision. This means that even though a
COMP-1 value can be up to 10 to the power of 38, it can only maintain about seven significant decimal digits.
Any value that has more than seven significant digits is rounded. This means that a COMP-1 value cannot
exactly represent a bank balance like $1,234,567.89 because this value has nine significant digits. Instead,
the amount is rounded. The main application of COMP-1 is for scientific numerical value storage as well as
computation.
10.1.1.2 COMP-2 This is also known as a double-precision floating-point number representation. COMP-
2 extends the range of values that can be represented compared to COMP-1. COMP-2 can represent values
up to about 10 to the power of 307. Like COMP-1, COMP-2 values also have limited precision. Due to the
expanded format, COMP-2 has more significant digits, approximately 15 decimal digits. This means that
once a value reaches certain quadrillions (with no decimal places), it can no longer be exactly represented in
COMP-2.
COMP-2 supersedes COMP-1 for more precise scientific data storage as well as computation. Note that
COMP-1 and COMP-2 have limited applications in financial data representation or computation.
10.1.1.3 COMP-3 This is also known as packed BCD (binary coded decimal) representation. This is,
by far, the most utilized numerical value representation in COBOL programs. Packed BCD is also somewhat
unique and native to mainframe computers such as the IBM z architecture.
100
Unlike COMP-1 or COMP-2, packed BCD has no inherent precision limitation that is independent of the
range of values. This is because COMP-3 is a variable-width format that depends on the actual value format.
COMP-3 exactly represents values with decimal places. A COMP-3 value can have up to 31 decimal digits.
10.1.1.4 COMP-4 COMP-4 is only capable of representing integers. Compared to COMP-1 and COMP-
2, COMP-4 can store and compute with integer values exactly (unless a division is involved). Although
COMP-3 can also be used to represent integer values, COMP-4 is more compact.
10.1.1.5 COMP-5 COMP-5 is based on COMP-4, but with the flexibility of specifying the position of a
decimal point. COMP-5 has the space efficiency of COMP-4 and the exactness of COMP-3. Unlike COMP-3,
however, a COMP-5 value cannot exceed 18 decimal digits.
10.1.2.1 EBCDIC Extended Binary Coded Decimal Interchange Code (EBCDIC) is an eight binary
digits character encoding standard, where the eight digital positions are divided into two pieces. EBCDIC
was devised in the early 1960s for IBM computers. EBCDIC is used to encode text data so that text can be
printed or displayed correctly on devices that also understand EBCDIC.
10.1.2.2 ASCII American Standard Code for Information Interchange, ASCII, is another binary digit
character encoding standard.
10.1.2.3 EBCDIC vs ASCII Why are these two standards when they seemingly perform the same
function?
EBCDIC is a standard that traces its root to punch cards designed in 1931. ASCII, on the other hand, is a
standard that was created, unrelated to IBM punch cards, in 1967. A COBOL program natively understands
EBCDIC, and it can comfortably process data originally captured in punch cards as early as 1931.
ASCII is mostly utilized by non-IBM computers.
COBOL can encode and process text data in EBCDIC or ASCII. This means a COBOL program can
simultaneously process data captured in a census many decades ago while exporting data to a cloud service
utilizing ASCII or Unicode. It is important to point out, however, that the programmer must have the
awareness and choose the appropriate encoding.
10.3 Lab
Many of the previous COBOL lab programs you have worked with thus far are reading records containing two
packed decimal fields, the client account limit and the client account balance. In the Arithmetic expressions
lab, the total of all client account limits and balances used a COMPUTE statement, where the COMP-3
fields contained the packed decimal internal data.
What happens when an internal packed decimal field is not described using COMP-3? Without using COMP-3
to describe the field, the COBOL program treats the data as DISPLAY data (EBCDIC format). This lab
demonstrates what happens during program execution without using COMP-3.
101
10.3.0.1 Using VS Code and Zowe Explorer
1. Submit the job, id.JCL(CBL0010J)
2. Observe that the compilation of the COBOL source was successful, however, also observe that the
execution of the job failed. How can you tell?
There’s no CC code next to CBL0010J(JOB#). Instead, there is an ABENDU4038 message. U4038 is
a common user code error typically involving a mismatch between the external data and the COBOL
representation of the data.
3. Read the execution SYSOUT message carefully. The SYSOUT message mistakenly believes the records
are 174 characters in length while the program believes the records are 170 characters in length.
Explanation: Packed decimal (COMP-3) expands into two numbers where only one number would
typically exist. If the program reads a packed decimal field without describing the field as COMP-3, then
program execution becomes confused about the size of the record because the PIC clause, S9(7)V99, is
expecting to store seven numbers plus a sign digit when only three word positions are read. Therefore,
execution reports a four-record length position discrepancy.
4. Edit id.CBL(CBL0010) to identify and correct the source code problem.*
5. Submit id.JCL(CBL0010J) and verify correction is successful with a CC 0000 code.
Lab Hints:
The ACCT-LIMIT PIC clause in the ACCT-FIELDS paragraph should be the same as the PIC clause for
ACCT-BALANCE.
102
11 Intrinsic functions
Today’s COBOL is not your parents’ COBOL. Today’s COBOL includes decades of feature/function-rich
advancements and performance improvements. Decades of industry specifications are applied to COBOL
to address the growing needs of businesses. What Enterprise COBOL for z/OS promised and delivered, is
decades of upward compatibility with new releases of hardware and operating system software. The original
DNA of COBOL evolved into a powerful, maintainable, trusted, and time-tested computer language with no
end in sight.
Among the new COBOL capabilities is JSON GENERATE and JSON PARSE, providing an easy to use
coding mechanism to transform DATA DIVISION defined data-items into JSON for a browser, a smartphone,
or any IoT (Internet of Things) device to format in addition to transforming JSON received from a browser,
a smartphone, or any IoT device into DATA DIVISION defined data-items for processing. Frequently, the
critical data accessed by a smartphone, such as a bank balance, is stored and controlled by z/OS where a
COBOL program is responsible for retrieving and returning the bank balance to the smartphone. COBOL
has become a web-enabled computer language.
Previous COBOL industry specifications included intrinsic functions, which remain largely relevant today.
An experienced COBOL programmer needs to be familiar with intrinsic functions and stay aware of any new
intrinsic functions introduced. This chapter aims to cover the foundation of intrinsic functions and their
usage in COBOL.
• What is an intrinsic function?
– Intrinsic function syntax
– Categories of intrinsic functions
• Intrinsic functions in Enterprise COBOL for z/OS V6.4
– Mathematical example
– Statistical example
– Date/time example
– Financial example
– Character-handling example
• Use of intrinsic functions with reference modifiers
• Lab
103
01 Item-1 Pic x (30) Value " Hello World ! " .
01 Item-2 Pic x (30) .
. . .
Display Item-1
Display Function Upper-case ( Item-1 )
Display Function Lower-case ( Item-1 )
Move Function Upper-case ( Item-1 ) to Item-2
Display Item-2
104
Example 2. Mathematical intrinsic function
105
11.2.5 Character-handling example
Example 6 shows a usage of the COBOL function UPPER-CASE where a string or alphabetic variables
processed by UPPER-CASE will translate any lower case characters to upper case.
MOVE FUNCTION UPPER-CASE ( " This is shouting ! " ) TO SOME-FIELD
DISPLAY SOME-FIELD
LNAME (1:1)
LNAME (4:2)
11.4 Lab
This lab contains data that includes a last name, where last name is all upper-case. It demonstrates the use
of intrinsic functions together with reference modification to lower-case the last name characters, except the
first character of the last name.
This lab requires two COBOL programs, CBL0011 and CBL0012, and two respective JCL Jobs, CBL0011J
and CBL0012J, to compile and execute the COBOL programs. All of which are provided to you in your VS
Code - Zowe Explorer.
106
Figure 1. Current lab vs. Data types lab output
3. Observe the PROCEDURE DIVISION intrinsic function, lower-case, within the WRITE-RECORD
paragraph. This intrinsic function is paired with a reference modification resulting in an output of last
name with upper-case first character and the remainder in lower-case.
4. Submit CBL0012J
5. Observe the compilation error.
Previous lab programs made use of a date/time intrinsic function. The date/time intrinsic function in this
lab has a syntax error that needs to be identified and corrected.
6. Modify id.CBL(CBL0012) correcting compilation error.*
7. Re-submit CBL0012J
8. Corrected CBL0012 source code should compile and execute the program successfully. A successful
compile will result in the same output as CBL0011J.
Lab Hints
Refer to CBL0011 line 120 for the proper formatting of the function-name causing the compilation error.
107
12 ABEND handling
When you do the labs on the previous chapters, you may have encountered an abnormal end or ABEND
for short. There are various categories of common COBOL errors which cause ABEND, and in production,
software errors can be costly - both in financial and reputation.
This chapter introduces ABEND and gives an overview of frequent ABEND types which a COBOL application
programmer may encounter. We will review possible reasons and frequent causes of the ABEND types for
the programmer to debug. We will also review some common best practices to avoid ABEND and review
reasons why a programmer may purposedly call an ABEND routine in their application.
• Why does ABEND happen?
• Frequent ABEND Types
– S001 - Record Length / Block Size Discrepancy
– S013 - Conflicting DCB Parameters
– S0C1 - Invalid Instruction
– S0C4 - Storage Protection Exception
– S0C7 - Data Exception
– S0CB - Division by Zero
– S222/S322 - Time Out / Job Cancelled
– S806 - Module Not Found
– B37/D37/E37 - Dataset or PDS Index Space Exceeded
• Best Practices to Avoid ABEND
• ABEND Routines
108
In the next sections, we will go through the ABENDs along with any possible reasons and the frequent causes
of the ABENDs. Note that the reasons and causes are non-exhaustive.
109
Frequent Causes: - Missing or incorrect JCL DD statement - Incorrect logic in table handling code -
Overflow of table entries - INITIALIZE a file FD that hasn’t been opened
110
12.3 Best Practices to Avoid ABEND
To avoid ABEND, we can do something called defensive programming. It is a form of programming where we
defensively design our code to ensure that it is still running under unforeseen circumstances.
By doing defensive programming, we can reduce the number of bugs and make the program more predictable
regardless of the inputs.
Listed below are some things we can do in COBOL:
• INITIALIZE fields at the beginning of a routine. This will ensure that the field has proper
data at the start of the program. However, special care needs to be taken to ensure that any flags or
accumulators have the appropriate INITIALIZE data.
• I/O statement checking. This can be through the use of FILE STATUS variable and checking
them before doing any further I/O operation. Additionally, we need to check for empty files and other
possible exceptions.
• Numeric fields checking. A general policy would be to not trust a numeric field we are doing math
on. Assume that the input can be invalid. It would be recommended to use ON OVERFLOW and ON
SIZE ERROR phrases to catch invalid or abnormal data. Special care should be taken when we need
to do rounding as truncation can occur in some cases.
• Code formatting. This will ensure that your code is maintainable and easy to understand by anyone
who is reading or maintaining them.
• Consistent use of scope terminators. It would be best practice to explicitly terminate a scope
using scope terminators such as END-IF, END-COMPUTE, or END-PERFORM.
• Testing, Checking, and Peer-Review. Proper tests and peer-review can be conducted to catch
possible errors that may have slipped through your program. Additionally, we can also ensure that the
business logic is correct.
Such routine can display more information which would allow you to determine where and why exactly has
the program failed.
111