0% found this document useful (0 votes)
530 views930 pages

Cobol Programming Guide V4R2

This edition applies to Version 4 Release 2 of IBM Enterprise COBOL for z / OS (program number 5655-S71) Make sure that you are using the correct edition for the level of the product. You can order publications online at www.ibm.com / shop / publications / order /, or order by phone or fax.

Uploaded by

DineshManivannan
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
530 views930 pages

Cobol Programming Guide V4R2

This edition applies to Version 4 Release 2 of IBM Enterprise COBOL for z / OS (program number 5655-S71) Make sure that you are using the correct edition for the level of the product. You can order publications online at www.ibm.com / shop / publications / order /, or order by phone or fax.

Uploaded by

DineshManivannan
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Enterprise COBOL for z/OS

Programming Guide
V ersion 4 Release 2

SC23-8529-01

Enterprise COBOL for z/OS

Programming Guide
V ersion 4 Release 2

SC23-8529-01

Note! Before using this information and the product it supports, be sure to read the general information under Notices on page 835.

Second Edition (August 2009) This edition applies to Version 4 Release 2 of IBM Enterprise COBOL for z/OS (program number 5655-S71) and to all subsequent releases and modifications until otherwise indicated in new editions. Make sure that you are using the correct edition for the level of the product. You can order publications online at www.ibm.com/shop/publications/order/, or order by phone or fax. IBM Software Manufacturing Solutions takes publication orders between 8:30 a.m. and 7:00 p.m. Eastern Standard Time (EST). The phone number is (800)879-2755. The fax number is (800)445-9269. You can also order publications through your IBM representative or the IBM branch office serving your locality. Copyright International Business Machines Corporation 1991, 2009. US Government Users Restricted Rights Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

Contents
Tables . . . . . . . . . . . . . . . xiii Preface . . . . . . . . . . . . . . xv
About this information . . . . . . . . . . xv How this document will help you . . . . . . xv Abbreviated terms . . . . . . . . . . . xv Comparison of commonly used terms . . . . xvi How to read syntax diagrams . . . . . . . xvi How examples are shown . . . . . . . . xviii Accessing softcopy documentation and support information. . . . . . . . . . . . . . xviii Summary of changes . . . . . . . . . . . xix Version 4 Release 2 (August 2009) . . . . . xix Version 4 Release 1 (December 2007) . . . . . xix How to send your comments . . . . . . . . xxi Accessibility . . . . . . . . . . . . . . xxi Interface information . . . . . . . . . . xxi Keyboard navigation . . . . . . . . . . xxi Accessibility of this information . . . . . . xxii IBM and accessibility. . . . . . . . . . xxii Examples: initializing data items . . . . . . Initializing a structure (INITIALIZE) . . . . . Assigning values to elementary data items (MOVE) . . . . . . . . . . . . . . Assigning values to group data items (MOVE) . Assigning arithmetic results (MOVE or COMPUTE) . . . . . . . . . . . . . Assigning input from a screen or file (ACCEPT) Displaying values on a screen or in a file (DISPLAY) Displaying data on the system logical output device . . . . . . . . . . . . . . . Using WITH NO ADVANCING . . . . . . Using intrinsic functions (built-in functions) . . . Using tables (arrays) and pointers . . . . . . . Storage and its addressability . . . . . . . . Settings for RMODE . . . . . . . . . . . Storage restrictions for passing data . . . . . Location of data areas . . . . . . . . . . Storage for LOCAL-STORAGE data . . . . . Storage for external data . . . . . . . . . Storage for QSAM input-output buffers . . . . 30 32 34 35 36 37 38 39 39 40 41 42 42 43 43 43 44 44

Part 1. Coding your program . . . . 1


Chapter 1. Structuring your program . . 5
Identifying a program . . . . . . . . . Identifying a program as recursive . . . . Marking a program as callable by containing programs . . . . . . . . . . . . Setting a program to an initial state. . . . Changing the header of a source listing . . Describing the computing environment . . . Example: FILE-CONTROL entries . . . . Specifying the collating sequence . . . . Defining symbolic characters . . . . . Defining a user-defined class . . . . . Defining files to the operating system . . Describing the data . . . . . . . . . . Using data in input and output operations . Comparison of WORKING-STORAGE and LOCAL-STORAGE . . . . . . . . . Using data from another program . . . . Processing the data . . . . . . . . . . How logic is divided in the PROCEDURE DIVISION . . . . . . . . . . . . Declaratives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 . 6 . 6 . 7 . 7 . 7 . 8 . 9 . 10 . 10 . 10 . 13 . 13 . 16 . 18 . 19 . 20 . 23

Chapter 3. Working with numbers and arithmetic . . . . . . . . . . . . . 45


Defining numeric data. . . . . . . . . . . Displaying numeric data . . . . . . . . . . Controlling how numeric data is stored . . . . . Formats for numeric data. . . . . . . . . . External decimal (DISPLAY and NATIONAL) items . . . . . . . . . . . . . . . External floating-point (DISPLAY and NATIONAL) items . . . . . . . . . . . Binary (COMP) items . . . . . . . . . . Native binary (COMP-5) items . . . . . . . Packed-decimal (COMP-3) items . . . . . . Internal floating-point (COMP-1 and COMP-2) items . . . . . . . . . . . . . . . Examples: numeric data and internal representation . . . . . . . . . . . . Data format conversions . . . . . . . . . . Conversions and precision . . . . . . . . Sign representation of zoned and packed-decimal data . . . . . . . . . . . . . . . . . Checking for incompatible data (numeric class test) Performing arithmetic . . . . . . . . . . . Using COMPUTE and other arithmetic statements . . . . . . . . . . . . . . Using arithmetic expressions . . . . . . . Using numeric intrinsic functions . . . . . . Using math-oriented callable services . . . . . Using date callable services . . . . . . . . Examples: numeric intrinsic functions . . . . Fixed-point contrasted with floating-point arithmetic Floating-point evaluations . . . . . . . . Fixed-point evaluations . . . . . . . . . 45 47 48 49 49 50 50 51 52 52 52 54 54 55 56 57 58 58 59 60 62 62 64 65 65

Chapter 2. Using data . . . . . . . . 25


Using variables, structures, literals, and Using variables . . . . . . . Using data items and group items . Using literals . . . . . . . . Using constants . . . . . . . Using figurative constants . . . Assigning values to data items . . .
Copyright IBM Corp. 1991, 2009

constants . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . .

25 25 26 27 28 28 29

iii

Arithmetic comparisons (relation conditions) Examples: fixed-point and floating-point evaluations . . . . . . . . . . . Using currency signs . . . . . . . . . Example: multiple currency signs . . . .

. . . .

. 65 . 66 . 67 . 68

Chapter 4. Handling tables . . . . . . 69


Defining a table (OCCURS) . . . . . . . . Nesting tables . . . . . . . . . . . . Example: subscripting . . . . . . . . . Example: indexing . . . . . . . . . . Referring to an item in a table . . . . . . . Subscripting . . . . . . . . . . . . Indexing . . . . . . . . . . . . . Putting values into a table . . . . . . . . Loading a table dynamically. . . . . . . Initializing a table (INITIALIZE) . . . . . Assigning values when you define a table (VALUE) . . . . . . . . . . . . . Example: PERFORM and subscripting . . . Example: PERFORM and indexing. . . . . Creating variable-length tables (DEPENDING ON) Loading a variable-length table . . . . . . Assigning values to a variable-length table . . Searching a table . . . . . . . . . . . Doing a serial search (SEARCH) . . . . . Doing a binary search (SEARCH ALL) . . . Processing table items using intrinsic functions . Example: processing tables using intrinsic functions . . . . . . . . . . . . . . . . . . . . . . . 69 71 72 72 72 73 74 75 75 76

Transforming to reverse order (REVERSE) . Converting to numbers (NUMVAL, NUMVAL-C) . . . . . . . . . . Converting from one code page to another Evaluating data items (intrinsic functions) . . Evaluating single characters for collating sequence . . . . . . . . . . . . Finding the largest or smallest data item . Finding the length of data items . . . . Finding the date of compilation . . . .

. . . . . . . .

. 113 . 113 . 115 . 115 . . . . 115 116 118 119

Chapter 7. Processing data in an international environment . . . . . . 121


COBOL statements and national data . . . . . Intrinsic functions and national data. . . . . . Unicode and the encoding of language characters Using national data (Unicode) in COBOL . . . . Defining national data items . . . . . . . Using national literals . . . . . . . . . Using national-character figurative constants Defining national numeric data items . . . . National groups . . . . . . . . . . . Using national groups . . . . . . . . . Storage of character data . . . . . . . . Converting to or from national (Unicode) representation . . . . . . . . . . . . . Converting alphanumeric, DBCS, and integer to national (MOVE) . . . . . . . . . . . Converting alphanumeric or DBCS to national (NATIONAL-OF) . . . . . . . . . . . Converting national to alphanumeric (DISPLAY-OF) . . . . . . . . . . . . Overriding the default code page. . . . . . Conversion exceptions . . . . . . . . . Example: converting to and from national data Processing UTF-8 data . . . . . . . . . . Processing Chinese GB 18030 data . . . . . . Comparing national (UTF-16) data . . . . . . Comparing two class national operands . . . Comparing class national and class numeric operands . . . . . . . . . . . . . . Comparing national numeric and other numeric operands . . . . . . . . . . . . . . Comparing national and other character-string operands . . . . . . . . . . . . . . Comparing national data and alphanumeric-group operands . . . . . . . Coding for use of DBCS support . . . . . . . Declaring DBCS data . . . . . . . . . . Using DBCS literals . . . . . . . . . . Testing for valid DBCS characters . . . . . Processing alphanumeric data items that contain DBCS data . . . . . . . . . . . . . 122 124 125 126 127 127 128 129 129 130 133 134 134 135 136 136 136 137 137 138 139 139 140 140 140 141 141 142 142 143 143

. 77 . 79 . 80 81 . 82 . 83 . 84 . 84 . 85 . 86 . 87

Chapter 5. Selecting and repeating program actions . . . . . . . . . . 89


Selecting program actions . . . . . . . . . 89 Coding a choice of actions . . . . . . . . 89 Coding conditional expressions . . . . . . . 94 Repeating program actions . . . . . . . . . 97 Choosing inline or out-of-line PERFORM . . . 98 Coding a loop . . . . . . . . . . . . 99 Looping through a table . . . . . . . . . 100 Executing multiple paragraphs or sections. . . 100

Chapter 6. Handling strings . . . . . 101


Joining data items (STRING) . . . . . . Example: STRING statement . . . . . Splitting data items (UNSTRING) . . . . Example: UNSTRING statement . . . . Manipulating null-terminated strings . . . Example: null-terminated strings . . . . Referring to substrings of data items . . . Reference modifiers . . . . . . . . Example: arithmetic expressions as reference modifiers . . . . . . . . . . . . Example: intrinsic functions as reference modifiers . . . . . . . . . . . . Tallying and replacing data items (INSPECT) . Examples: INSPECT statement. . . . . Converting data items (intrinsic functions). . Converting to uppercase or lowercase (UPPER-CASE, LOWER-CASE) . . . . . . . . . . . . . . . . . . . . . . . . . . 101 102 103 104 106 107 107 109

. 110 . . . . 110 111 111 112

Chapter 8. Processing files . . . . . 145


File organization and input-output devices Choosing file organization and access mode Format for coding input and output . . Allocating files . . . . . . . . . . Checking for input or output errors . . . . . . . . . . . . . . . . . . 145 147 148 149 150

. 113

iv

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 9. Processing QSAM files . . 151


Defining QSAM files and records in COBOL . . . Establishing record formats. . . . . . . . Setting block sizes . . . . . . . . . . . Coding input and output statements for QSAM files . . . . . . . . . . . . . . . . Opening QSAM files . . . . . . . . . . Dynamically creating QSAM files. . . . . . Adding records to QSAM files. . . . . . . Updating QSAM files . . . . . . . . . Writing QSAM files to a printer or spooled data set . . . . . . . . . . . . . . . . Closing QSAM files . . . . . . . . . . Handling errors in QSAM files . . . . . . . Working with QSAM files . . . . . . . . . Defining and allocating QSAM files . . . . . Retrieving QSAM files . . . . . . . . . Ensuring that file attributes match your program . . . . . . . . . . . . . . Using striped extended-format QSAM data sets Accessing HFS files using QSAM . . . . . . . Labels for QSAM files . . . . . . . . . . Using trailer and header labels . . . . . . Format of standard labels . . . . . . . . Processing QSAM ASCII files on tape . . . . . Processing ASCII file labels . . . . . . . . . 151 152 159 161 162 163 163 164 164 165 165 166 166 169 170 172 174 174 175 176 177 178

Defining line-sequential files and records in COBOL . . . . . . . . . . . . . . . Allowable control characters . . . . . . . Describing the structure of a line-sequential file Defining and allocating line-sequential files . . . Coding input-output statements for line-sequential files . . . . . . . . . . . . . . . . Opening line-sequential files . . . . . . . Reading records from line-sequential files . . . Adding records to line-sequential files . . . . Closing line-sequential files. . . . . . . . Handling errors in line-sequential files . . . . .

207 208 208 209 209 210 210 211 211 212

Chapter 12. Sorting and merging files

213
214 214 215 215 216 217 218 218 219 219 220 220 221 222 223 223 224 224 225 225 226 226 227 228 229 230 231 231 231 232

Chapter 10. Processing VSAM files

179
180 181 182 182 184 185 185 187 189 189 192 193 193 194 194 194 195 196 196 197 197 198 200 202 203

VSAM files . . . . . . . . . . . . . . Defining VSAM file organization and records . . Specifying sequential organization for VSAM files . . . . . . . . . . . . . . . Specifying indexed organization for VSAM files Specifying relative organization for VSAM files Specifying access modes for VSAM files . . . Defining record lengths for VSAM files. . . . Coding input and output statements for VSAM files . . . . . . . . . . . . . . . . File position indicator . . . . . . . . . Opening a file (ESDS, KSDS, or RRDS) . . . . Reading records from a VSAM file . . . . . Updating records in a VSAM file . . . . . . Adding records to a VSAM file . . . . . . Replacing records in a VSAM file. . . . . . Deleting records from a VSAM file . . . . . Closing VSAM files . . . . . . . . . . Handling errors in VSAM files . . . . . . . Protecting VSAM files with a password . . . . Example: password protection for a VSAM indexed file . . . . . . . . . . . . . Working with VSAM data sets under z/OS and z/OS UNIX . . . . . . . . . . . . . . Defining VSAM files . . . . . . . . . . Creating alternate indexes . . . . . . . . Allocating VSAM files . . . . . . . . . Sharing VSAM files through RLS . . . . . . Improving VSAM performance . . . . . . .

Sort and merge process . . . . . . . . . . Describing the sort or merge file . . . . . . . Describing the input to sorting or merging . . . Example: describing sort and input files for SORT . . . . . . . . . . . . . . . Coding the input procedure . . . . . . . . Describing the output from sorting or merging . . Coding the output procedure . . . . . . . . Example: coding the output procedure when using DFSORT . . . . . . . . . . . . Restrictions on input and output procedures . . . Defining sort and merge data sets . . . . . . Sorting variable-length records . . . . . . . Requesting the sort or merge . . . . . . . . Setting sort or merge criteria . . . . . . . Example: sorting with input and output procedures . . . . . . . . . . . . . Choosing alternate collating sequences . . . . Sorting on windowed date fields . . . . . . Preserving the original sequence of records with equal keys . . . . . . . . . . . . . Determining whether the sort or merge was successful . . . . . . . . . . . . . . Stopping a sort or merge operation prematurely Improving sort performance with FASTSRT . . . FASTSRT requirements for JCL . . . . . . FASTSRT requirements for sort input and output files . . . . . . . . . . . . . Checking for sort errors with NOFASTSRT . . . Controlling sort behavior . . . . . . . . . Changing DFSORT defaults with control statements . . . . . . . . . . . . . Allocating storage for sort or merge operations Allocating space for sort files . . . . . . . Using checkpoint/restart with DFSORT . . . . Sorting under CICS . . . . . . . . . . . CICS SORT application restrictions . . . . .

Chapter 13. Handling errors . . . . . 233


Requesting dumps . . . . . . . . . . Handling errors in joining and splitting strings . Handling errors in arithmetic operations . . . Example: checking for division by zero . . . Handling errors in input and output operations Using the end-of-file condition (AT END) . . Coding ERROR declaratives . . . . . . . . . . 233 234 234 235 235 . 238 . 238

Chapter 11. Processing line-sequential files . . . . . . . . . . . . . . . 207

Contents

Using file status keys . . . . . . . . . Example: file status key . . . . . . . . Using VSAM status codes (VSAM files only) Example: checking VSAM status codes . . . Coding INVALID KEY phrases . . . . . Example: FILE STATUS and INVALID KEY . Handling errors when calling programs . . . Writing routines for handling errors . . . . .

. 239 . 240 241 . 241 . 243 . 243 . 244 . 244

Setting environment variables under z/OS UNIX Specifying compiler options under z/OS UNIX . Compiling and linking with the cob2 command Creating a DLL under z/OS UNIX . . . . Example: using cob2 to compile and link under z/OS UNIX . . . . . . . . . . . . cob2 syntax and options . . . . . . . . cob2 input and output files . . . . . . . Compiling using scripts . . . . . . . . .

283 . 284 285 . 286 . . . . 287 287 289 290

Part 2. Compiling and debugging your program . . . . . . . . . . 247


Chapter 14. Compiling under z/OS 249
249 250 259 261 262 262 263 264 265 267 267 268 269 269 269 270 270 270 271 271 272 273 273 273 274 275 276 277 278 279 279 280 280 281 Compiling with JCL . . . . . . . . . . . Using a cataloged procedure . . . . . . . Writing JCL to compile programs. . . . . . Compiling under TSO . . . . . . . . . . Example: ALLOCATE and CALL for compiling under TSO . . . . . . . . . . . . . Example: CLIST for compiling under TSO . . . Starting the compiler from an assembler program Defining compiler input and output . . . . . . Data sets used by the compiler under z/OS . . Defining the source code data set (SYSIN) . . . Defining a compiler-option data set (SYSOPTF) Specifying source libraries (SYSLIB) . . . . . Defining the output data set (SYSPRINT) . . . Directing compiler messages to your terminal (SYSTERM) . . . . . . . . . . . . . Creating object code (SYSLIN or SYSPUNCH) Defining an associated-data file (SYSADATA) Defining the Java-source output file (SYSJAVA) Defining the debug data set (SYSDEBUG) . . . Defining the library-processing output file (SYSMDECK) . . . . . . . . . . . . Specifying compiler options under z/OS . . . . Specifying compiler options with the PROCESS (CBL) statement . . . . . . . . . . . Example: specifying compiler options using JCL Example: specifying compiler options under TSO . . . . . . . . . . . . . . . Compiler options and compiler output under z/OS . . . . . . . . . . . . . . . Compiling multiple programs (batch compilation) Example: batch compilation . . . . . . . Specifying compiler options in a batch compilation . . . . . . . . . . . . . Example: precedence of options in a batch compilation . . . . . . . . . . . . . Example: LANGUAGE option in a batch compilation . . . . . . . . . . . . . Correcting errors in your source program . . . . Generating a list of compiler messages . . . . Messages and listings for compiler-detected errors . . . . . . . . . . . . . . . Format of compiler diagnostic messages . . . Severity codes for compiler diagnostic messages

Chapter 16. Compiling, linking, and running OO applications . . . . . . 291


Compiling, linking, and running OO applications under z/OS UNIX. . . . . . . . . . . . Compiling OO applications under z/OS UNIX Preparing OO applications under z/OS UNIX Example: compiling and linking a COBOL class definition under z/OS UNIX . . . . . . . Running OO applications under z/OS UNIX Compiling, linking, and running OO applications in JCL or TSO/E . . . . . . . . . . . . Compiling OO applications in JCL or TSO/E Preparing and running OO applications in JCL or TSO/E. . . . . . . . . . . . . . Example: compiling, linking, and running an OO application using JCL . . . . . . . . Using Java SDKs for z/OS . . . . . . . . . Object-oriented syntax, and Java 5 or Java 6 SDKs . . . . . . . . . . . . . . . 291 291 292 293 293 295 296 296 298 299 300

| | |

Chapter 17. Compiler options . . . . 301


Option settings for Standard conformance. . . . . . Conflicting compiler options ADATA . . . . . . . ADV . . . . . . . . ARITH . . . . . . . AWO . . . . . . . . BLOCK0 . . . . . . . BUFSIZE . . . . . . . CICS . . . . . . . . CODEPAGE . . . . . . COMPILE . . . . . . CURRENCY . . . . . . DATA . . . . . . . . DATEPROC . . . . . . DBCS . . . . . . . . DECK . . . . . . . . DIAGTRUNC . . . . . DLL . . . . . . . . DUMP . . . . . . . DYNAM . . . . . . . EXIT . . . . . . . . EXPORTALL . . . . . FASTSRT . . . . . . . FLAG . . . . . . . . FLAGSTD . . . . . . INTDATE . . . . . . LANGUAGE . . . . . LIB . . . . . . . . . COBOL 85 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 304 305 305 306 307 307 309 309 310 313 313 314 315 317 317 318 318 319 320 321 321 322 322 323 325 326 327

Chapter 15. Compiling under z/OS UNIX . . . . . . . . . . . . . . . 283 vi


Enterprise COBOL for z/OS V4.2 Programming Guide

LINECOUNT . . . . . . LIST . . . . . . . . . MAP . . . . . . . . . MDECK . . . . . . . . NAME . . . . . . . . NSYMBOL . . . . . . . NUMBER . . . . . . . NUMPROC . . . . . . . OBJECT . . . . . . . . OFFSET . . . . . . . . OPTFILE . . . . . . . . OPTIMIZE . . . . . . . OUTDD . . . . . . . . PGMNAME . . . . . . . PGMNAME(COMPAT) . . PGMNAME(LONGUPPER). PGMNAME(LONGMIXED) Usage notes . . . . . . QUOTE/APOST . . . . . RENT . . . . . . . . . RMODE . . . . . . . . SEQUENCE . . . . . . . SIZE . . . . . . . . . SOURCE . . . . . . . . SPACE . . . . . . . . SQL . . . . . . . . . SQLCCSID . . . . . . . SSRANGE . . . . . . . TERMINAL . . . . . . . TEST . . . . . . . . . THREAD . . . . . . . . TRUNC . . . . . . . . TRUNC example 1 . . . TRUNC example 2 . . . VBREF . . . . . . . . WORD . . . . . . . . XMLPARSE . . . . . . . XREF . . . . . . . . . YEARWINDOW . . . . . ZWB . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

327 328 328 329 331 331 332 333 334 335 335 336 337 338 339 339 340 340 340 341 342 343 344 344 345 345 347 347 348 349 352 353 355 355 356 356 357 358 360 360

Getting listings . . . . . . . . . . Example: short listing . . . . . . Example: SOURCE and NUMBER output Example: MAP output . . . . . . Reading LIST output . . . . . . . Example: XREF output: data-name cross-references. . . . . . . . . Example: OFFSET compiler output . . Example: VBREF compiler output . .

. . . . . . . .

. . . . . . . .

. . . . .

377 379 381 382 387

. 398 . 402 . 403

Part 3. Targeting COBOL programs for certain environments . . . . . 405


Chapter 20. Developing COBOL programs for CICS . . . . . . . . . 407
Coding COBOL programs to run under CICS Getting the system date under CICS. . . Calling to or from COBOL programs . . Determining the success of ECI calls. . . Compiling with the CICS option . . . . . Separating CICS suboptions . . . . . Integrated CICS translator . . . . . . Using the separate CICS translator . . . . CICS reserved-word table . . . . . . . Handling errors by using CICS HANDLE . . Example: handling errors by using CICS HANDLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407 409 409 411 411 413 413 414 415 416

. 417

Chapter 21. Programming for a DB2 environment . . . . . . . . . . . . 419


DB2 coprocessor . . . . . . . . . . . . Coding SQL statements . . . . . . . . . . Using SQL INCLUDE with the DB2 coprocessor Using character data in SQL statements . . . Using national decimal data in SQL statements Using national group items in SQL statements Using binary items in SQL statements . . . . Determining the success of SQL statements . . Compiling with the SQL option . . . . . . . Separating DB2 suboptions . . . . . . . . COBOL and DB2 CCSID determination. . . . . Code-page determination for string host variables in SQL statements . . . . . . . Programming with the SQLCCSID or NOSQLCCSID option . . . . . . . . . Differences in how the DB2 precompiler and coprocessor behave . . . . . . . . . . . Period at the end of EXEC SQL INCLUDE statements . . . . . . . . . . . . . EXEC SQL INCLUDE and nested COPY REPLACING . . . . . . . . . . . . EXEC SQL and REPLACE or COPY REPLACING . . . . . . . . . . . . Source code after an END-EXEC statement . . Multiple definitions of host variables . . . . EXEC SQL statement continuation lines . . . Bit-data host variables . . . . . . . . . SQL-INIT-FLAG . . . . . . . . . . . 419 420 420 421 422 422 423 423 423 424 425 426 426 427 427 427 428 428 428 428 428 429

Chapter 18. Compiler-directing statements . . . . . . . . . . . . 363 Chapter 19. Debugging . . . . . . . 367


Debugging with source language . . . . . Tracing program logic . . . . . . . Finding and handling input-output errors . Validating data . . . . . . . . . . Finding uninitialized data . . . . . . Generating information about procedures . Debugging using compiler options . . . . Finding coding errors . . . . . . . Finding line sequence problems . . . . Checking for valid ranges . . . . . . Selecting the level of error to be diagnosed Finding program entity definitions and references . . . . . . . . . . . Listing data items . . . . . . . . . Using the debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 368 369 369 370 370 372 372 373 373 374

. 376 . 376 . 377

Contents

vii

Choosing the DYNAM or NODYNAM compiler option . . . . . . . . . . . . . . .

. 429

Chapter 22. Developing COBOL programs for IMS. . . . . . . . . . 431


Compiling and linking COBOL programs for running under IMS . . . . . . . . . . . Using object-oriented COBOL and Java under IMS Calling a COBOL method from a Java application under IMS . . . . . . . . . Building a mixed COBOL-Java application that starts with COBOL . . . . . . . . . . Writing mixed-language IMS applications . . . 431 432 432 433 434

Handling null-terminated strings . . . . . Using pointers to process a chained list . . Passing return-code information . . . . . . Understanding the RETURN-CODE special register . . . . . . . . . . . . . Using PROCEDURE DIVISION RETURNING . .. . . . . . . . . . . . . . . . Specifying CALL . . . RETURNING . . . . Sharing data by using the EXTERNAL clause. . Sharing files between programs (external files) . Example: using external files . . . . . .

. 470 . 471 . 474 . . . . . . . 474 474 475 475 475 476

Chapter 26. Creating a DLL or a DLL application . . . . . . . . . . . . 481


Dynamic link libraries (DLLs) . . . . . . . . Compiling programs to create DLLs . . . . . . Linking DLLs . . . . . . . . . . . . . Example: sample JCL for a procedural DLL application . . . . . . . . . . . . . . Prelinking certain DLLs . . . . . . . . . . Using CALL identifier with DLLs . . . . . . Search order for DLLs in the HFS . . . . . Using DLL linkage and dynamic calls together . . Using procedure or function pointers with DLLs Calling DLLs from non-DLLs . . . . . . . Example: calling DLLs from non-DLLs . . . . Using COBOL DLLs with C/C++ programs . . . Using DLLs in OO COBOL applications . . . . 481 482 483 484 485 485 486 486 488 488 489 490 491

Chapter 23. Running COBOL programs under z/OS UNIX . . . . . 437


Running in z/OS UNIX environments . . . . Setting and accessing environment variables . . Setting environment variables that affect execution . . . . . . . . . . . . . Runtime environment variables . . . . . Example: setting and accessing environment variables . . . . . . . . . . . . . Calling UNIX/POSIX APIs . . . . . . . . Accessing main program parameters . . . . Example: accessing main program parameters . 437 . 438 . 439 . 439 . 440 . 440 . 442 443

Part 4. Structuring complex applications . . . . . . . . . . . 445


Chapter 24. Using subprograms . . . 447
Main programs, subprograms, and calls . . . . Ending and reentering main programs or subprograms . . . . . . . . . . . . . Transferring control to another program . . . . Making static calls. . . . . . . . . . . Making dynamic calls . . . . . . . . . AMODE switching . . . . . . . . . . Performance considerations of static and dynamic calls . . . . . . . . . . . . Making both static and dynamic calls . . . . Examples: static and dynamic CALL statements Calling nested COBOL programs . . . . . . Making recursive calls . . . . . . . . . . Calling to and from object-oriented programs . . Using procedure and function pointers . . . . . Deciding which type of pointer to use . . . . Calling alternate entry points . . . . . . . Making programs reentrant . . . . . . . . 447 448 449 450 451 453 455 455 456 458 461 461 462 463 463 464

Chapter 27. Preparing COBOL programs for multithreading . . . . . 493


Multithreading . . . . . . . . . . . . Choosing THREAD to support multithreading . Transferring control to multithreaded programs Ending multithreaded programs . . . . . . Processing files with multithreading . . . . . File-definition (FD) storage . . . . . . . Serializing file access with multithreading . . Example: usage patterns of file input and output with multithreading. . . . . . . Handling COBOL limitations with multithreading . 494 . 495 495 . 496 . 496 . 497 . 497 . 498 499

Part 5. Using XML and COBOL together . . . . . . . . . . . . . 501


Chapter 28. Processing XML input
XML parser in COBOL . . . . . . . . . Accessing XML documents . . . . . . . . Parsing XML documents . . . . . . . . Writing procedures to process XML . . . . XML events . . . . . . . . . . . . Transforming XML text to COBOL data items Parsing XML documents with validation . . Parsing XML documents one segment at a time The encoding of XML documents. . . . . . XML input document encoding . . . . . Parsing XML documents encoded in UTF-8 . Handling XML PARSE exceptions . . . . . How the XML parser handles errors. . . .

503
. . . . . . . . . . . 504 506 506 508 510 514 515 518 520 521 525 526 528

Chapter 25. Sharing data . . . . . . 465


Passing data . . . . . . . . . . . . . Describing arguments in the calling program Describing parameters in the called program Testing for OMITTED arguments . . . . . Coding the LINKAGE SECTION . . . . . . Coding the PROCEDURE DIVISION for passing arguments . . . . . . . . . . . . . Grouping data to be passed . . . . . . . 465 467 468 . 468 . 469 . 469 . 470

viii

Enterprise COBOL for z/OS V4.2 Programming Guide

| |

Handling encoding conflicts . . . . Terminating XML parsing . . . . . . XML PARSE examples . . . . . . . Example: parsing a simple document . Example: program for processing XML . Example: parsing an XML document that namespaces . . . . . . . . . . Example: parsing an XML document one segment at a time . . . . . . . . Example: parsing XML documents with validation . . . . . . . . . .

. . . . . . . . . . uses . . . . . .

. . . . .

529 530 531 531 532

. 535 . 537 . 539

Chapter 29. Producing XML output

543
543 547 548 549 549 550 553 553 554 557

Generating XML output . . . . . . . . . . Controlling the encoding of generated XML output Handling XML GENERATE exceptions . . . . . Example: generating XML . . . . . . . . . Program XGFX . . . . . . . . . . . . Program Pretty . . . . . . . . . . . . Output from program XGFX . . . . . . . Enhancing XML output . . . . . . . . . . Example: enhancing XML output . . . . . . Example: converting hyphens in element or attribute names to underscores . . . . . .

Defining a subclass . . . . . . . . . . . CLASS-ID paragraph for defining a subclass REPOSITORY paragraph for defining a subclass WORKING-STORAGE SECTION for defining subclass instance data . . . . . . . . . Defining a subclass instance method . . . . Example: defining a subclass (with methods) Defining a factory section . . . . . . . . . WORKING-STORAGE SECTION for defining factory data . . . . . . . . . . . . . Defining a factory method . . . . . . . . Example: defining a factory (with methods) . . Wrapping procedure-oriented COBOL programs Structuring OO applications . . . . . . . . Examples: COBOL applications that run using the java command . . . . . . . . . . .

589 590 591 592 592 592 594 594 595 597 603 603 604

Chapter 31. Communicating with Java methods . . . . . . . . . . . . . 607


Accessing JNI services . . . . . . . . . . Handling Java exceptions . . . . . . . . Managing local and global references . . . . Java access controls . . . . . . . . . . Sharing data with Java . . . . . . . . . . Coding interoperable data types in COBOL and Java . . . . . . . . . . . . . . . Declaring arrays and strings for Java . . . . Manipulating Java arrays . . . . . . . . Manipulating Java strings . . . . . . . . Example: J2EE client written in COBOL . . . . COBOL client (ConverterClient.cbl) . . . . . Java client (ConverterClient.java) . . . . . . 607 608 610 611 612 612 613 614 616 619 619 621

Part 6. Developing object-oriented programs . . . . . . . . . . . . 559


Chapter 30. Writing object-oriented programs . . . . . . . . . . . . . 561
Example: accounts. . . . . . . . . . . Subclasses . . . . . . . . . . . . Defining a class . . . . . . . . . . . CLASS-ID paragraph for defining a class . . REPOSITORY paragraph for defining a class WORKING-STORAGE SECTION for defining class instance data . . . . . . . . . . Example: defining a class . . . . . . . Defining a class instance method . . . . . . METHOD-ID paragraph for defining a class instance method . . . . . . . . . . INPUT-OUTPUT SECTION for defining a class instance method . . . . . . . . . . DATA DIVISION for defining a class instance method . . . . . . . . . . . . . PROCEDURE DIVISION for defining a class instance method . . . . . . . . . . Overriding an instance method . . . . . Overloading an instance method . . . . . Coding attribute (get and set) methods . . . Example: defining a method . . . . . . Defining a client . . . . . . . . . . . REPOSITORY paragraph for defining a client DATA DIVISION for defining a client . . . Comparing and setting object references . . Invoking methods (INVOKE) . . . . . . Creating and initializing instances of classes . Freeing instances of classes . . . . . . . Example: defining a client . . . . . . . . . . . 562 563 564 566 566

Part 7. Specialized processing . . 623


Chapter 32. Interrupts and checkpoint/restart . . . . . . . . . 625
Setting checkpoints . . . . . . . . . . . Designing checkpoints . . . . . . . . . Testing for a successful checkpoint . . . . . DD statements for defining checkpoint data sets Messages generated during checkpoint . . . . Restarting programs . . . . . . . . . . . Requesting automatic restart . . . . . . . Requesting deferred restart . . . . . . . . Formats for requesting deferred restart . . . . Resubmitting jobs for restart . . . . . . . Example: restarting a job at a specific checkpoint step. . . . . . . . . . . . Example: requesting a step restart . . . . . Example: resubmitting a job for a step restart Example: resubmitting a job for a checkpoint restart . . . . . . . . . . . . . . . 625 626 627 627 628 628 629 629 630 631 631 631 632 632

. 568 . 569 . 569 . 570 . 571 . 571 . . . . . . . . . . . . 572 573 574 575 576 578 579 580 581 582 586 588 589

Chapter 33. Processing two-digit-year dates . . . . . . . . . . . . . . . 635


Millennium language extensions (MLE) . . . Principles and objectives of these extensions . Resolving date-related logic problems . . . .
Contents

. 636 . 636 . 637

ix

Using a century window . . . . . . . . Using internal bridging . . . . . . . . . Moving to full field expansion. . . . . . . Using year-first, year-only, and year-last date fields Compatible dates . . . . . . . . . . . Example: comparing year-first date fields . . . Using other date formats . . . . . . . . Example: isolating the year . . . . . . . . Manipulating literals as dates . . . . . . . . Assumed century window . . . . . . . . Treatment of nondates . . . . . . . . . Setting triggers and limits . . . . . . . . . Example: using limits . . . . . . . . . Using sign conditions . . . . . . . . . Sorting and merging by date . . . . . . . . Example: sorting by date and time . . . . . Performing arithmetic on date fields. . . . . . Allowing for overflow from windowed date fields . . . . . . . . . . . . . . . Specifying the order of evaluation . . . . . Controlling date processing explicitly . . . . . Using DATEVAL . . . . . . . . . . . Using UNDATE . . . . . . . . . . . Example: DATEVAL . . . . . . . . . . Example: UNDATE . . . . . . . . . . Analyzing and avoiding date-related diagnostic messages . . . . . . . . . . . . . . . Avoiding problems in processing dates . . . . . Avoiding problems with packed-decimal fields Moving from expanded to windowed date fields

638 639 641 643 643 644 644 645 645 646 647 648 649 650 650 651 651 652 653 653 654 654 655 655 656 657 657 658

Sample list of Language Environment callable services . . . . . . . . . . . . . Calling Language Environment services . . Example: Language Environment callable services . . . . . . . . . . . . .

. 682 . 683 . 684

Part 9. Appendixes . . . . . . . . 685


Appendix A. Intermediate results and arithmetic precision . . . . . . . . 687
Terminology used for intermediate results . . . . Example: calculation of intermediate results . . . Fixed-point data and intermediate results . . . . Addition, subtraction, multiplication, and division . . . . . . . . . . . . . . Exponentiation . . . . . . . . . . . . Example: exponentiation in fixed-point arithmetic . . . . . . . . . . . . . Truncated intermediate results. . . . . . . Binary data and intermediate results . . . . Intrinsic functions evaluated in fixed-point arithmetic . . . . . . . . . . . . . . Integer functions . . . . . . . . . . . Mixed functions . . . . . . . . . . . Floating-point data and intermediate results . . . Exponentiations evaluated in floating-point arithmetic . . . . . . . . . . . . . Intrinsic functions evaluated in floating-point arithmetic . . . . . . . . . . . . . Arithmetic expressions in nonarithmetic statements 688 689 689 689 690 691 692 692 692 692 693 694 695 695 695

Part 8. Improving performance and productivity . . . . . . . . . . . 659


Chapter 34. Tuning your program . . . 661
Using an optimal programming style . . . Using structured programming . . . . Factoring expressions. . . . . . . . Using symbolic constants . . . . . . Grouping constant computations . . . . Grouping duplicate computations . . . Choosing efficient data types . . . . . . Choosing efficient computational data items Using consistent data types. . . . . . Making arithmetic expressions efficient . . Making exponentiations efficient . . . . Handling tables efficiently . . . . . . . Optimization of table references . . . . Optimizing your code . . . . . . . . Optimization . . . . . . . . . . Choosing compiler features to enhance performance . . . . . . . . . . . . Performance-related compiler options . . Evaluating performance . . . . . . . Running efficiently with CICS, IMS, or VSAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662 662 662 663 663 663 664 664 665 665 665 665 667 669 669 671 672 675 676

Appendix B. Complex OCCURS DEPENDING ON . . . . . . . . . . 697


Example: complex ODO . . . . . . . . . How length is calculated . . . . . . . Setting values of ODO objects . . . . . . Effects of change in ODO object value . . . . Preventing index errors when changing ODO object value . . . . . . . . . . . . Preventing overlay when adding elements to a variable table . . . . . . . . . . . . . . . 697 698 698 698

. 699 . 699

Appendix C. Converting double-byte character set (DBCS) data . . . . . . 703


DBCS notation . . . . . . . . . . . . . Alphanumeric to DBCS data conversion (IGZCA2D) . . . . . . . . . . . . . . IGZCA2D syntax . . . . . . . . . . . IGZCA2D return codes . . . . . . . . . Example: IGZCA2D . . . . . . . . . . DBCS to alphanumeric data conversion (IGZCD2A) IGZCD2A syntax . . . . . . . . . . . IGZCD2A return codes . . . . . . . . . Example: IGZCD2A . . . . . . . . . . 703 703 704 704 705 706 706 707 707

Chapter 35. Simplifying coding . . . . 679


Eliminating repetitive coding . . . . . . . Example: using the COPY statement. . . . Using Language Environment callable services . . 679 . 680 . 681

Appendix D. XML reference material

709

XML PARSE exceptions with XMLPARSE(XMLSS) in effect . . . . . . . . . . . . . . . 709

Enterprise COBOL for z/OS V4.2 Programming Guide

XML PARSE exceptions with XMLPARSE(COMPAT) in effect . . . . . . . 711 XML PARSE exceptions that allow continuation 711 XML PARSE exceptions that do not allow continuation . . . . . . . . . . . . . 715 XML GENERATE exceptions . . . . . . . . 718

Appendix E. EXIT compiler option . . 719


Using the user-exit work area . . . . . . Calling from exit modules . . . . . . . Processing of INEXIT. . . . . . . . . INEXIT parameters . . . . . . . . Processing of LIBEXIT . . . . . . . . Processing of LIBEXIT with nested COPY statements . . . . . . . . . . . LIBEXIT parameters . . . . . . . . Processing of PRTEXIT . . . . . . . . PRTEXIT parameters . . . . . . . . Processing of ADEXIT . . . . . . . . ADEXIT parameters . . . . . . . . Processing of MSGEXIT . . . . . . . . MSGEXIT parameters . . . . . . . Customizing compiler-message severities . Error handling for exit modules . . . . . Using the EXIT compiler option with CICS and SQL statements . . . . . . . . . . . Example: MSGEXIT user exit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721 721 722 722 723 724 725 726 726 727 728 729 729 730 733

Compilation unit start|end record: X0002 Options record: X0010 . . . . . . . External symbol record: X0020 . . . . Parse tree record: X0024 . . . . . . Token record: X0030. . . . . . . . Source error record: X0032 . . . . . Source record: X0038 . . . . . . . COPY REPLACING record: X0039 . . . Symbol record: X0042 . . . . . . . Symbol cross-reference record: X0044 . . Nested program record: X0046 . . . . Library record: X0060 . . . . . . . Statistics record: X0090 . . . . . . . EVENTS record: X0120 . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

753 754 763 764 779 792 793 794 794 807 808 809 809 810

Appendix H. Using sample programs


IGYTCARA: batch application . . . . Input data for IGYTCARA . . . . Report produced by IGYTCARA . . Preparing to run IGYTCARA . . . IGYTCARB: interactive program . . . Preparing to run IGYTCARB . . . IGYTSALE: nested program application Input data for IGYTSALE . . . . Reports produced by IGYTSALE . . Preparing to run IGYTSALE . . . Language elements and concepts that are illustrated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

815
. . . . . . . . . . 815 816 817 818 819 820 822 823 825 828

| | | | |

. 734 . 735

. 829

Appendix F. JNI.cpy

. . . . . . . . 741 Notices . . . . . . . . . . . . . . 835


Trademarks . . . . . . . . . . . . . . 837

Appendix G. COBOL SYSADATA file contents . . . . . . . . . . . . . 747


Existing compiler options that affect the SYSADATA file . . . . . . . . . SYSADATA record types . . . . . Example: SYSADATA . . . . . . SYSADATA record descriptions . . . Common header section . . . . . . Job identification record: X0000 . . . ADATA identification record: X0001 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747 748 749 750 751 752 753

Glossary . . . . . . . . . . . . . 839 List of resources . . . . . . . . . . 873


Enterprise COBOL for z/OS Related publications . . . . . . . . . . . . . . . . . . 873 . 873

Index . . . . . . . . . . . . . . . 875

Contents

xi

xii

Enterprise COBOL for z/OS V4.2 Programming Guide

Tables
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. FILE-CONTROL entries . . . . . . . . 8 FILE SECTION entries . . . . . . . . 14 Assignment to data items in a program 29 Effect of RMODE and RENT compiler options on the RMODE attribute . . . . . 42 Ranges in value of COMP-5 data items 51 Internal representation of numeric items 53 NUMCLS(PRIM) and valid signs . . . . . 57 NUMCLS(ALT) and valid signs . . . . . 57 Order of evaluation of arithmetic operators 59 Numeric intrinsic functions . . . . . . . 60 Compatibility of math intrinsic functions and callable services . . . . . . . . . . . 61 INTDATE(LILIAN) and compatibility of date intrinsic functions and callable services. . . 62 INTDATE(ANSI) and compatibility of date intrinsic functions and callable services. . . 62 Hexadecimal values of the euro sign . . . . 67 COBOL statements and national data 122 Intrinsic functions and national character data. . . . . . . . . . . . . . . 124 National group items that are processed with group semantics . . . . . . . . 132 Encoding and size of alphanumeric, DBCS, and national data . . . . . . . . . . 133 Summary of file organizations, access modes, and record formats of COBOL files . 147 QSAM file allocation. . . . . . . . . 167 Maximum record length of QSAM files 171 Handling of QSAM user labels . . . . . 176 Identifiers for standard tape labels . . . . 176 Comparison of VSAM, COBOL, and non-VSAM terminology. . . . . . . . 179 Comparison of VSAM data-set types 181 VSAM file organization, access mode, and record format . . . . . . . . . . . 182 Definition of VSAM fixed-length records 186 Definition of VSAM variable-length records 186 I/O statements for VSAM sequential files 188 I/O statements for VSAM relative and indexed files . . . . . . . . . . . 188 Statements to load records into a VSAM file 191 Statements to update records in a VSAM file . . . . . . . . . . . . . . . 193 Methods for improving VSAM performance 203 Methods for checking for sort errors with NOFASTSRT . . . . . . . . . . . 228 Methods for controlling sort behavior 228 Compiler data sets . . . . . . . . . 265 Block size of fixed-length compiler data sets 267 Block size of variable-length compiler data sets . . . . . . . . . . . . . . . 267 Types of compiler output under z/OS 273 Severity codes for compiler diagnostic messages . . . . . . . . . . . . . 281 Input files to the cob2 command . . . . . 289 42. Output files from the cob2 command 43. Commands for compiling and linking a class definition . . . . . . . . . . . 44. java command options for customizing the JVM . . . . . . . . . . . . . . 45. Compiler options . . . . . . . . . . 46. Mutually exclusive compiler options 47. EBCDIC multibyte coded character set identifiers . . . . . . . . . . . . 48. Values of the LANGUAGE compiler option 49. Severity levels of compiler messages 50. Using compiler options to get listings 51. Terms used in MAP output . . . . . . 52. Symbols used in LIST and MAP output 53. Signature information bytes for compiler options . . . . . . . . . . . . . 54. Signature information bytes for the DATA DIVISION . . . . . . . . . . . . 55. Signature information bytes for the ENVIRONMENT DIVISION . . . . . . 56. Signature information bytes for PROCEDURE DIVISION verbs . . . . . 57. Signature information bytes for more PROCEDURE DIVISION items . . . . . 58. Calls between COBOL and assembler under CICS . . . . . . . . . . . . . . 59. Compiler options required for the integrated CICS translator . . . . . . . . . . . 60. Compiler options required for the separate CICS translator . . . . . . . . . . . 61. TRUNC compiler options recommended for the separate CICS translator . . . . . . 62. Compiler options required with the DB2 coprocessor . . . . . . . . . . . . 63. Samples with POSIX function calls . . . . 64. Effects of termination statements. . . . . 65. Methods for passing data in the CALL statement . . . . . . . . . . . . . 66. Compiler options for DLL applications 67. Binder options for DLL applications 68. Special registers used by the XML parser 69. Result of processing-procedure changes to XML-CODE with XMLPARSE(XMLSS) in effect . . 70. Result of processing-procedure changes to XML-CODE with XMLPARSE(COMPAT) in effect . . 71. Coded character sets for XML documents 72. Hexadecimal values of white-space characters. . . . . . . . . . . . . 73. Aliases for XML encoding declarations 74. Hexadecimal values of special characters for various EBCDIC CCSIDs . . . . . . . 75. XML events and special registers . . . . 76. XML events and special registers . . . . 77. Encoding of generated XML if the ENCODING phrase is omitted . . . . . 78. Structure of class definitions . . . . . . 289 292 294 301 304 312 326 374 377 384 385 390 391 392 392 394 410 412 415 415 424 441 448 466 482 483 508 511 511 521 522 524 524 531 536 547 564

| | | | | |

Copyright IBM Corp. 1991, 2009

xiii

| |

79. Structure of instance method definitions 80. Structure of COBOL clients . . . . . . 81. Conformance of arguments in a COBOL client . . . . . . . . . . . . . . 82. Conformance of the returned data item in a COBOL client . . . . . . . . . . . 83. Structure of factory definitions . . . . . 84. Structure of factory method definitions 85. JNI services for local and global references 86. Interoperable data types in COBOL and Java 87. Interoperable arrays and strings in COBOL and Java . . . . . . . . . . . . . 88. Noninteroperable array types in COBOL and Java . . . . . . . . . . . . . 89. JNI array services . . . . . . . . . . 90. Services that convert between jstring references and national data . . . . . . 91. Services that convert between jstring references and alphanumeric data . . . . 92. Advantages and disadvantages of Year 2000 solutions . . . . . . . . . . . . . 93. Performance-related compiler options 94. Performance-tuning worksheet . . . . . 95. Language Environment callable services 96. IGZCA2D return codes . . . . . . . . 97. IGZCD2A return codes . . . . . . . . 98. Reason codes for XML PARSE exceptions that are unique to Enterprise COBOL . . . 99. XML PARSE exceptions that allow continuation (for XMLPARSE(COMPAT)) . . . . 100. XML PARSE exceptions that do not allow continuation (for XMLPARSE(COMPAT)) . . . . 101. XML GENERATE exceptions . . . . . . 102. Layout of the user-exit work area . . . . 103. INEXIT processing . . . . . . . . . 104. INEXIT parameters . . . . . . . . . 105. LIBEXIT processing . . . . . . . . . 106. LIBEXIT processing with nonnested COPY statements . . . . . . . . . . . . 107. LIBEXIT processing with nested COPY statements . . . . . . . . . . . .

570 578 583 585 594 595 611 612 613 614 614 617 617 638 672 675 682 705 707 709 711

| | |

108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135.

715 718 721 722 722 723 724 724

136. 137. 138. 139.

LIBEXIT parameters . . . . . . . . . PRTEXIT processing . . . . . . . . . PRTEXIT parameters . . . . . . . . . ADEXIT processing . . . . . . . . . ADEXIT parameters . . . . . . . . . MSGEXIT processing . . . . . . . . MSGEXIT parameters . . . . . . . . FIPS (FLAGSTD) message categories . . . . Actions possible in exit modules for CICS and SQL statements . . . . . . . . . SYSADATA record types . . . . . . . SYSADATA common header section SYSADATA job identification record ADATA identification record . . . . . . SYSADATA compilation unit start|end record . . . . . . . . . . . . . . SYSADATA options record . . . . . . . SYSADATA external symbol record SYSADATA parse tree record . . . . . . SYSADATA token record . . . . . . . SYSADATA source error record . . . . . SYSADATA source record . . . . . . . SYSADATA COPY REPLACING record SYSADATA symbol record . . . . . . . SYSADATA symbol cross-reference record SYSADATA nested program record . . . . SYSADATA library record . . . . . . . SYSADATA statistics record . . . . . . SYSADATA EVENTS TIMESTAMP record layout . . . . . . . . . . . . . . SYSADATA EVENTS PROCESSOR record layout . . . . . . . . . . . . . . SYSADATA EVENTS FILE END record layout . . . . . . . . . . . . . . SYSADATA EVENTS PROGRAM record layout . . . . . . . . . . . . . . SYSADATA EVENTS FILE ID record layout SYSADATA EVENTS ERROR record layout

725 726 726 727 728 729 729 732 734 748 751 752 753 754 754 764 764 779 793 793 794 794 807 808 809 809 810 810 811 811 811 812

xiv

Enterprise COBOL for z/OS V4.2 Programming Guide

Preface
About this information
Welcome to IBM Enterprise COBOL for z/OS, IBMs latest host COBOL compiler! This version of IBM COBOL adds new COBOL function to help integrate COBOL business processes and Web-oriented business processes by: v Simplifying the componentization of COBOL programs and enabling interoperability with Java components v Promoting the exchange and use of data in standardized formats, including XML and Unicode

How this document will help you


This document will help you write and compile Enterprise COBOL programs. It will also help you define object-oriented classes and methods, invoke methods, and refer to objects in your programs. This document assumes experience in developing application programs and some knowledge of COBOL. It focuses on using Enterprise COBOL to meet your programming objectives and not on the definition of the COBOL language. For complete information about COBOL syntax, see the IBM Enterprise COBOL Language Reference. For information about migrating programs to Enterprise COBOL, see the IBM Enterprise COBOL Compiler and Runtime Migration Guide. IBM z/OS Language Environment provides the runtime environment and runtime services that are required to run Enterprise COBOL programs. You can find information about link-editing and running programs in the IBM z/OS Language Environment Programming Guide and IBM z/OS Language Environment Programming Reference. For a comparison of commonly used Enterprise COBOL and Language Environment terms, see Comparison of commonly used terms on page xvi.

Abbreviated terms
Certain terms are used in a shortened form in this information. Abbreviations for the product names used most frequently are listed alphabetically in the following table.
Term used CICS

Long form CICS Transaction Server IBM Enterprise COBOL for z/OS IBM z/OS Language Environment MVS/ESA

Enterprise COBOL Language Environment MVS

Copyright IBM Corp. 1991, 2009

xv

Term used z/OS UNIX

Long form z/OS UNIX System Services

In addition to these abbreviated terms, the term Standard COBOL 85 is used to refer to the combination of the following standards: v ISO 1989:1985, Programming languages - COBOL v ISO/IEC 1989/AMD1:1992, Programming languages - COBOL: Intrinsic function module v ISO/IEC 1989/AMD2:1994, Programming languages - Correction and clarification amendment for COBOL v ANSI INCITS 23-1985, Programming Languages - COBOL v ANSI INCITS 23a-1989, Programming Languages - Intrinsic Function Module for COBOL v ANSI INCITS 23b-1993, Programming Language - Correction Amendment for COBOL The ISO standards are identical to the American National standards. Other terms, if not commonly understood, are shown in italics the first time that they appear, and are listed in the glossary.

Comparison of commonly used terms


To better understand the terms used throughout the IBM z/OS Language Environment and IBM Enterprise COBOL for z/OS information, and to understand which terms are meant to be equivalent, see the following table.
Language Environment term Aggregate Array Array element Enclave External data Local data Pass parameters directly, by value Pass parameters indirectly, by reference Enterprise COBOL equivalent Group item A table created using the OCCURS clause Table element Run unit WORKING-STORAGE data defined using the EXTERNAL clause Any non-EXTERNAL data item BY VALUE BY REFERENCE

Pass parameters indirectly, by value BY CONTENT Routine Scalar Program Elementary item

How to read syntax diagrams


Use the following description to read the syntax diagrams in this information. v Read the syntax diagrams from left to right, from top to bottom, following the path of the line. The >>--- symbol indicates the beginning of a syntax diagram.

xvi

Enterprise COBOL for z/OS V4.2 Programming Guide

The ---> symbol indicates that the syntax diagram is continued on the next line. The >--- symbol indicates that the syntax diagram is continued from the previous line. The --->< symbol indicates the end of a syntax diagram. Diagrams of syntactical units other than complete statements start with the >--symbol and end with the ---> symbol. v Required items appear on the horizontal line (the main path):

required_item

v Optional items appear below the main path:

required_item optional_item

v If you can choose from two or more items, they appear vertically, in a stack. If you must choose one of the items, one item of the stack appears on the main path:

required_item

required_choice1 required_choice2

If choosing one of the items is optional, the entire stack appears below the main path:

required_item optional_choice1 optional_choice2

If one of the items is the default, it appears above the main path and the remaining choices are shown below:

default_choice required_item optional_choice optional_choice

v An arrow returning to the left, above the main line, indicates an item that can be repeated:
Preface

xvii

required_item

repeatable_item

If the repeat arrow contains a comma, you must separate repeated items with a comma:

, required_item repeatable_item

v Keywords appear in uppercase (for example, FROM). They must be spelled exactly as shown. Variables appear in lowercase italics (for example, column-name). They represent user-supplied names or values. v If punctuation marks, parentheses, arithmetic operators, or other such symbols are shown, you must enter them as part of the syntax.

How examples are shown


This information shows numerous examples of sample COBOL statements, program fragments, and small programs to illustrate the coding techniques being described. The examples of program code are written in lowercase, uppercase, or mixed case to demonstrate that you can write your programs in any of these ways. To more clearly separate some examples from the explanatory text, they are presented in a monospace font. COBOL keywords and compiler options that appear in text are generally shown in SMALL UPPERCASE. Other terms such as program variable names are sometimes shown in an italic font for clarity.

Accessing softcopy documentation and support information


IBM Enterprise COBOL for z/OS provides PDF and BookManager versions of the library on the product site at www.ibm.com/software/awdtools/cobol/zos/ library/. You can check that Web site for the latest editions. In the BookManager version of a document, the content of some tables and syntax diagrams might be aligned improperly due to variations in the display technology. Support information is also available on the product site at www.ibm.com/ software/awdtools/cobol/zos/support/.

xviii

Enterprise COBOL for z/OS V4.2 Programming Guide

Summary of changes
This section lists the major changes that have been made to Enterprise COBOL in Version 4. The changes that are described in this information have an associated cross-reference for your convenience. The latest technical changes are marked by a vertical bar (|) in the left margin in the PDF and BookManager versions. | | | | | | | | | | | | | | | | | | | | | | | | | | | |

Version 4 Release 2 (August 2009)


v New and enhanced XML PARSE capabilities are available when you use the z/OS XML System Services parser: You can parse documents with validation against an XML schema when you use the VALIDATING phrase of the XML PARSE statement (Parsing XML documents with validation on page 515). The performance of nonvalidating parsing is improved. Character processing is enhanced for any XML document that contains a reference to a character that is not included in the single-byte EBCDIC code page of the document. For further details, see the Enterprise COBOL Compiler and Runtime Migration Guide. v A facility for customizing compiler diagnostic messages and FIPS messages by changing their severity or suppressing them is made possible by a new suboption, MSGEXIT, of the EXIT compiler option (Processing of MSGEXIT on page 729). v A new compiler option, BLOCK0, activates an implicit BLOCK CONTAINS 0 clause for all eligible QSAM files in your program (BLOCK0 on page 307). v The underscore character (_) is now supported in user-defined words such as data-names and program-names. Underscores are also supported in the literal form of program-names. For further details, see the Enterprise COBOL Language Reference. v If you use the integrated CICS translator, the compiler listing will now show the CICS options that are in effect. v Enterprise COBOL applications that use object-oriented syntax for Java interoperability are now supported with Java 5 and Java 6 in addition to the Java SDK 1.4.2 (Object-oriented syntax, and Java 5 or Java 6 SDKs on page 300).

Version 4 Release 1 (December 2007)


v The performance of operations on Unicode (USAGE NATIONAL) data has been significantly improved. The compiler now generates z/Architecture hardware instructions for most Unicode MOVE operations and comparisons. v A new compiler option, XMLPARSE, makes it possible to choose between parsing with the parser that is available with the COBOL library (for compatibility with Enterprise COBOL Version 3) or with the z/OS XML System Services parser (XMLPARSE on page 357). v New XML PARSE capabilities are available when you parse a document using the z/OS XML System Services parser (Chapter 28, Processing XML input, on page 503): Namespaces and namespace prefixes are processed using new special registers and new XML events. You can specify the document encoding using the ENCODING phrase of the XML PARSE statement.
Preface

xix

You can parse documents that are encoded in Unicode UTF-8 (Parsing XML documents encoded in UTF-8 on page 525). The RETURNING NATIONAL phrase enables you to receive XML document fragments in Unicode regardless of the original encoding of an XML document. You can parse documents that reside in a data set or parse very large documents a buffer at a time (Parsing XML documents one segment at a time on page 518). v The XML GENERATE statement has been enhanced (Chapter 29, Producing XML output, on page 543): You can specify a namespace using the NAMESPACE phrase, and a namespace prefix to be applied to each element using the NAMESPACE-PREFIX phrase. You can specify the code page of the generated document using the ENCODING phrase (Controlling the encoding of generated XML output on page 547). XML documents can now be generated in UTF-8 as well as in UTF-16 or various EBCDIC code pages. The WITH ATTRIBUTES phrase causes eligible elementary items to be expressed as attributes rather than as child elements in the generated XML. The WITH XML-DECLARATION phrase causes an XML declaration to be generated. v A new compiler option, OPTFILE, enables the specifying of COBOL compiler options from within a data set (OPTFILE on page 335). v Compiler listings now cross-reference copybooks and the data sets from which copybooks are obtained (Example: XREF output: COPY/BASIS cross-references on page 400). v Support for new features of DB2 for z/OS V9 is enabled when you use the integrated DB2 coprocessor (SQL compiler option) (DB2 coprocessor on page 419): New SQL data types are supported: XML types, BINARY, VARBINARY, BIGINT, and file reference variables. New SQL syntax for XML manipulation, enhancements to large object manipulation, MERGE, and SELECT FROM MERGE is supported. DB2 processing options STDSQL(YES|NO), NOFOR, and SQL(ALL|DB2) are supported as suboptions to the SQL compiler option (Compiling with the SQL option on page 423). v Several usability enhancements to COBOL-DB2 applications are available when you use the integrated DB2 coprocessor: The compiler listing is enhanced to show the DB2 options in effect (if you use DB2 for z/OS V9) and to show the expansion of the SQLCA and SQLDA control blocks. You can specify an alternate ddname for DBRMLIB when you invoke the compiler from an assembler language program (Starting the compiler from an assembler program on page 263). An explicitly coded LOCAL-STORAGE SECTION or WORKING-STORAGE SECTION is no longer required. v Debugging has been enhanced to support Debug Tool V8. A new suboption of the TEST compiler option, EJPD, enables the Debug Tool commands JUMPTO and GOTO for production debugging. The TEST compiler option has been simplified and has restructured suboptions (TEST on page 349).

xx

Enterprise COBOL for z/OS V4.2 Programming Guide

How to send your comments


Your feedback is important in helping us to provide accurate, high-quality information. If you have comments about this information or any other Enterprise COBOL documentation, contact us in one of these ways: v Fill out the Readers Comments Form and return it by mail or give it to an IBM representative. If there is no Readers Comments Form at the back, address your comments to: IBM Corporation Reader Comments DTX/E269 555 Bailey Avenue San Jose, CA 95141-1003 USA v Use the Online Readers Comments Form at www.ibm.com/software/awdtools/ rcf/. v Send your comments to the following e-mail address: [email protected]. Be sure to include the name of the document, the publication number, the version of Enterprise COBOL, and, if applicable, the specific location (for example, the page number or section heading) of the text that you are commenting on. When you send information to IBM, you grant IBM a nonexclusive right to use or distribute the information in any way that IBM believes appropriate without incurring any obligation to you.

Accessibility
Accessibility features help users who have a disability, such as restricted mobility or limited vision, to use software products successfully. The accessibility features in z/OS provide accessibility for Enterprise COBOL. The major accessibility features in z/OS are: v Interfaces that are commonly used by screen readers and screen-magnifier software v Keyboard-only navigation v Ability to customize display attributes such as color, contrast, and font size

Interface information
Assistive technology products work with the user interfaces that are found in z/OS. For specific guidance information, see the documentation for the assistive technology product that you use to access z/OS interfaces.

Keyboard navigation
Users can access z/OS user interfaces by using TSO/E or ISPF. For information about accessing TSO/E or ISPF interfaces, see the following publications: v z/OS TSO/E Primer v z/OS TSO/E Users Guide v z/OS ISPF Users Guide Volume I
Preface

xxi

These guides describe how to use TSO/E and ISPF, including the use of keyboard shortcuts or function keys (PF keys). Each guide includes the default settings for the PF keys and explains how to modify their functions.

Accessibility of this information


The English-language XHTML format of this information that will be provided in the IBM System z Enterprise Development Tools & Compilers Information Center at publib.boulder.ibm.com/infocenter/pdthelp/index.jsp is accessible to visually impaired individuals who use a screen reader. To enable your screen reader to accurately read syntax diagrams, source code examples, and text that contains the period or comma PICTURE symbols, you must set the screen reader to speak all punctuation. | | |

IBM and accessibility


See the IBM Human Ability and Accessibility Center at www.ibm.com/able for more information about the commitment that IBM has to accessibility.

xxii

Enterprise COBOL for z/OS V4.2 Programming Guide

Part 1. Coding your program


Chapter 1. Structuring your program . . . . . 5 Identifying a program . . . . . . . . . . . 5 Identifying a program as recursive . . . . . . 6 Marking a program as callable by containing programs . . . . . . . . . . . . . . 6 Setting a program to an initial state. . . . . . 7 Changing the header of a source listing . . . . 7 Describing the computing environment . . . . . 7 Example: FILE-CONTROL entries . . . . . . 8 Specifying the collating sequence . . . . . . 9 Example: specifying the collating sequence . . 9 Defining symbolic characters . . . . . . . 10 Defining a user-defined class . . . . . . . 10 Defining files to the operating system . . . . 10 Varying the input or output file at run time . 11 Optimizing buffer and device space . . . . 12 Describing the data . . . . . . . . . . . . 13 Using data in input and output operations . . . 13 FILE SECTION entries. . . . . . . . . 14 Comparison of WORKING-STORAGE and LOCAL-STORAGE . . . . . . . . . . . 16 Example: storage sections. . . . . . . . 17 Using data from another program . . . . . . 18 Sharing data in separately compiled programs 18 Sharing data in nested programs . . . . . 18 Sharing data in recursive or multithreaded programs . . . . . . . . . . . . . 19 Processing the data . . . . . . . . . . . . 19 How logic is divided in the PROCEDURE DIVISION . . . . . . . . . . . . . . 20 Imperative statements . . . . . . . . . 21 Conditional statements . . . . . . . . 21 Compiler-directing statements . . . . . . 22 Scope terminators . . . . . . . . . . 22 Declaratives . . . . . . . . . . . . . 23 Chapter 2. Using data . . . . . . . . . . Using variables, structures, literals, and constants . Using variables . . . . . . . . . . . . Using data items and group items . . . . . . Using literals . . . . . . . . . . . . . Using constants . . . . . . . . . . . . Using figurative constants . . . . . . . . Assigning values to data items . . . . . . . . Examples: initializing data items . . . . . . Initializing a structure (INITIALIZE) . . . . . Assigning values to elementary data items (MOVE) . . . . . . . . . . . . . . Assigning values to group data items (MOVE) . Assigning arithmetic results (MOVE or COMPUTE) . . . . . . . . . . . . . Assigning input from a screen or file (ACCEPT) Displaying values on a screen or in a file (DISPLAY) Displaying data on the system logical output device . . . . . . . . . . . . . . . Using WITH NO ADVANCING . . . . . .
Copyright IBM Corp. 1991, 2009

Using intrinsic functions (built-in functions) Using tables (arrays) and pointers . . . . Storage and its addressability . . . . . Settings for RMODE . . . . . . . . Storage restrictions for passing data . . Location of data areas . . . . . . . Storage for LOCAL-STORAGE data . . Storage for external data . . . . . . Storage for QSAM input-output buffers .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

40 41 42 42 43 43 43 44 44 45 45 47 48 49 49 50 50 51 52 52 52 54 54 54 55 55 55 56 57 58 58 59 60 62 62 63 63 63 64 64 64 65 65 65 66 67 68

25 25 25 26 27 28 28 29 30 32 34 35 36 37 38 39 39

Chapter 3. Working with numbers and arithmetic Defining numeric data. . . . . . . . . . . Displaying numeric data . . . . . . . . . . Controlling how numeric data is stored . . . . . Formats for numeric data. . . . . . . . . . External decimal (DISPLAY and NATIONAL) items . . . . . . . . . . . . . . . External floating-point (DISPLAY and NATIONAL) items . . . . . . . . . . . Binary (COMP) items . . . . . . . . . . Native binary (COMP-5) items . . . . . . . Packed-decimal (COMP-3) items . . . . . . Internal floating-point (COMP-1 and COMP-2) items . . . . . . . . . . . . . . . Examples: numeric data and internal representation . . . . . . . . . . . . Data format conversions . . . . . . . . . . Conversions and precision . . . . . . . . Conversions that lose precision . . . . . . Conversions that preserve precision . . . . Conversions that result in rounding . . . . Sign representation of zoned and packed-decimal data . . . . . . . . . . . . . . . . . Checking for incompatible data (numeric class test) Performing arithmetic . . . . . . . . . . . Using COMPUTE and other arithmetic statements . . . . . . . . . . . . . . Using arithmetic expressions . . . . . . . Using numeric intrinsic functions . . . . . . Using math-oriented callable services . . . . . Using date callable services . . . . . . . . Examples: numeric intrinsic functions . . . . General number handling . . . . . . . Date and time . . . . . . . . . . . Finance . . . . . . . . . . . . . . Mathematics . . . . . . . . . . . . Statistics . . . . . . . . . . . . . Fixed-point contrasted with floating-point arithmetic Floating-point evaluations . . . . . . . . Fixed-point evaluations . . . . . . . . . Arithmetic comparisons (relation conditions) . . Examples: fixed-point and floating-point evaluations . . . . . . . . . . . . . Using currency signs . . . . . . . . . . . Example: multiple currency signs . . . . . .

Chapter 4. Handling tables. . . . . . . . Defining a table (OCCURS) . . . . . . . . Nesting tables . . . . . . . . . . . . Example: subscripting . . . . . . . . . Example: indexing . . . . . . . . . . Referring to an item in a table . . . . . . . Subscripting . . . . . . . . . . . . Indexing . . . . . . . . . . . . . Putting values into a table . . . . . . . . Loading a table dynamically. . . . . . . Initializing a table (INITIALIZE) . . . . . Assigning values when you define a table (VALUE) . . . . . . . . . . . . . Initializing each table item individually . . Initializing a table at the group level . . . Initializing all occurrences of a given table element. . . . . . . . . . . . . Example: PERFORM and subscripting . . . Example: PERFORM and indexing. . . . . Creating variable-length tables (DEPENDING ON) Loading a variable-length table . . . . . . Assigning values to a variable-length table . . Searching a table . . . . . . . . . . . Doing a serial search (SEARCH) . . . . . Example: serial search . . . . . . . . Doing a binary search (SEARCH ALL) . . . Example: binary search . . . . . . . Processing table items using intrinsic functions . Example: processing tables using intrinsic functions . . . . . . . . . . . . .

. . . . . . . . . . .

69 69 71 72 72 72 73 74 75 75 76

. 77 . 77 . 78 . 78 . 79 . 80 81 . 82 . 83 . 84 . 84 . 84 . 85 . 86 . 86 . 87

Referring to substrings of data items . . . Reference modifiers . . . . . . . . Example: arithmetic expressions as reference modifiers . . . . . . . . . . . . Example: intrinsic functions as reference modifiers . . . . . . . . . . . . Tallying and replacing data items (INSPECT) . Examples: INSPECT statement. . . . . Converting data items (intrinsic functions). . Converting to uppercase or lowercase (UPPER-CASE, LOWER-CASE) . . . . Transforming to reverse order (REVERSE) . Converting to numbers (NUMVAL, NUMVAL-C) . . . . . . . . . . Converting from one code page to another Evaluating data items (intrinsic functions) . . Evaluating single characters for collating sequence . . . . . . . . . . . . Finding the largest or smallest data item . Returning variable-length results with alphanumeric or national functions . . Finding the length of data items . . . . Finding the date of compilation . . . .

. . . . . . . . . . . . . . . . .

. 107 . 109 . 110 . . . . 110 111 111 112

. 113 . 113 . 113 . 115 . 115 . 115 . 116 . 117 . 118 . 119

Chapter 5. Selecting and repeating program actions . . . . . . . . . . . . . . . 89 Selecting program actions . . . . . . . . . 89 Coding a choice of actions . . . . . . . . 89 Using nested IF statements . . . . . . . 90 Using the EVALUATE statement . . . . . 91 Coding conditional expressions . . . . . . . 94 Switches and flags . . . . . . . . . . 95 Defining switches and flags . . . . . . . 95 Example: switches . . . . . . . . . . 95 Example: flags . . . . . . . . . . . 96 Resetting switches and flags . . . . . . . 96 Example: set switch on . . . . . . . . 96 Example: set switch off . . . . . . . . 97 Repeating program actions . . . . . . . . . 97 Choosing inline or out-of-line PERFORM . . . 98 Example: inline PERFORM statement . . . . 98 Coding a loop . . . . . . . . . . . . 99 Looping through a table . . . . . . . . . 100 Executing multiple paragraphs or sections. . . 100 Chapter 6. Handling strings . . . . . . . . 101 Joining data items (STRING) . . . . . . . . 101 Example: STRING statement . . . . . . . 102 STRING results. . . . . . . . . . . 103 Splitting data items (UNSTRING) . . . . . . 103 Example: UNSTRING statement . . . . . . 104 UNSTRING results . . . . . . . . . 105 Manipulating null-terminated strings . . . . . 106 Example: null-terminated strings . . . . . . 107

Chapter 7. Processing data in an international environment . . . . . . . . . . . . . COBOL statements and national data . . . . . Intrinsic functions and national data. . . . . . Unicode and the encoding of language characters Using national data (Unicode) in COBOL . . . . Defining national data items . . . . . . . Using national literals . . . . . . . . . Using national-character figurative constants Defining national numeric data items . . . . National groups . . . . . . . . . . . Using national groups . . . . . . . . . Using national groups as elementary items Using national groups as group items . . . Storage of character data . . . . . . . . Converting to or from national (Unicode) representation . . . . . . . . . . . . . Converting alphanumeric, DBCS, and integer to national (MOVE) . . . . . . . . . . . Converting alphanumeric or DBCS to national (NATIONAL-OF) . . . . . . . . . . . Converting national to alphanumeric (DISPLAY-OF) . . . . . . . . . . . . Overriding the default code page. . . . . . Conversion exceptions . . . . . . . . . Example: converting to and from national data Processing UTF-8 data . . . . . . . . . . Processing Chinese GB 18030 data . . . . . . Comparing national (UTF-16) data . . . . . . Comparing two class national operands . . . Comparing class national and class numeric operands . . . . . . . . . . . . . . Comparing national numeric and other numeric operands . . . . . . . . . . . . . . Comparing national and other character-string operands . . . . . . . . . . . . . .

121 122 124 125 126 127 127 128 129 129 130 131 132 133 134 134 135 136 136 136 137 137 138 139 139 140 140 140

Enterprise COBOL for z/OS V4.2 Programming Guide

Comparing national data and alphanumeric-group operands . . . . Coding for use of DBCS support . . . . Declaring DBCS data . . . . . . . Using DBCS literals . . . . . . . Testing for valid DBCS characters . . Processing alphanumeric data items that DBCS data . . . . . . . . . . Chapter 8. Processing files . . . . . File organization and input-output devices Choosing file organization and access mode Format for coding input and output . . Allocating files . . . . . . . . . . Checking for input or output errors . . .

. . . . . . . . . . . . . . . contain . . .

141 141 142 142 143 143

. . . 145 . . . 145 . . . 147 . . . 148 . . . 149 . . . 150 151 151 152 152 153 154 156 158 159 161 162 163 163 164 164 165 165 166 166 169 169 170 170 171 172 172 173 174 174 175 176 177 177 178 179 180 181 182 182 183

Chapter 9. Processing QSAM files . . . . . Defining QSAM files and records in COBOL . . . Establishing record formats. . . . . . . . Logical records . . . . . . . . . . . Requesting fixed-length format . . . . . Requesting variable-length format . . . . Requesting spanned format. . . . . . . Requesting undefined format . . . . . . Setting block sizes . . . . . . . . . . . Coding input and output statements for QSAM files . . . . . . . . . . . . . . . . Opening QSAM files . . . . . . . . . . Dynamically creating QSAM files. . . . . . Adding records to QSAM files. . . . . . . Updating QSAM files . . . . . . . . . Writing QSAM files to a printer or spooled data set . . . . . . . . . . . . . . . . Closing QSAM files . . . . . . . . . . Handling errors in QSAM files . . . . . . . Working with QSAM files . . . . . . . . . Defining and allocating QSAM files . . . . . Parameters for creating QSAM files . . . . Retrieving QSAM files . . . . . . . . . Parameters for retrieving QSAM files . . . Ensuring that file attributes match your program . . . . . . . . . . . . . . Processing existing files . . . . . . . . Processing new files . . . . . . . . . Using striped extended-format QSAM data sets Allocation of buffers for QSAM files. . . . Accessing HFS files using QSAM . . . . . . . Labels for QSAM files . . . . . . . . . . Using trailer and header labels . . . . . . Format of standard labels . . . . . . . . Standard user labels . . . . . . . . . Processing QSAM ASCII files on tape . . . . . Processing ASCII file labels . . . . . . . . . Chapter 10. Processing VSAM files . . . . . VSAM files . . . . . . . . . . . . . . Defining VSAM file organization and records . . Specifying sequential organization for VSAM files . . . . . . . . . . . . . . . Specifying indexed organization for VSAM files Using alternate keys . . . . . . . . .

Using an alternate index. . . . . . . . Specifying relative organization for VSAM files Fixed-length and variable-length RRDS . . . Using variable-length RRDS . . . . . . Specifying access modes for VSAM files . . . Example: using dynamic access with VSAM files . . . . . . . . . . . . . . Defining record lengths for VSAM files. . . . Defining fixed-length records . . . . . . Defining variable-length records . . . . . Coding input and output statements for VSAM files . . . . . . . . . . . . . . . . File position indicator . . . . . . . . . Opening a file (ESDS, KSDS, or RRDS) . . . . Opening an empty file . . . . . . . . Statements to load records into a VSAM file Opening a loaded file (a file with records) Reading records from a VSAM file . . . . . Updating records in a VSAM file . . . . . . Adding records to a VSAM file . . . . . . Replacing records in a VSAM file. . . . . . Deleting records from a VSAM file . . . . . Closing VSAM files . . . . . . . . . . Handling errors in VSAM files . . . . . . . Protecting VSAM files with a password . . . . Example: password protection for a VSAM indexed file . . . . . . . . . . . . . Working with VSAM data sets under z/OS and z/OS UNIX . . . . . . . . . . . . . . Defining VSAM files . . . . . . . . . . Creating alternate indexes . . . . . . . . Example: entries for alternate indexes . . . Allocating VSAM files . . . . . . . . . Sharing VSAM files through RLS . . . . . . Preventing update problems with VSAM files in RLS mode . . . . . . . . . . . Restrictions when using RLS . . . . . . Handling errors in VSAM files in RLS mode Improving VSAM performance . . . . . . .

183 184 184 184 185 185 185 186 186 187 189 189 190 191 191 192 193 193 194 194 194 195 196 196 197 197 198 199 200 202 202 203 203 203

Chapter 11. Processing line-sequential files . . 207 Defining line-sequential files and records in COBOL . . . . . . . . . . . . . . . 207 Allowable control characters . . . . . . . 208 Describing the structure of a line-sequential file 208 Defining and allocating line-sequential files . . . 209 Coding input-output statements for line-sequential files . . . . . . . . . . . . . . . . 209 Opening line-sequential files . . . . . . . 210 Reading records from line-sequential files . . . 210 Adding records to line-sequential files . . . . 211 Closing line-sequential files. . . . . . . . 211 Handling errors in line-sequential files . . . . . 212 Chapter 12. Sorting and merging files . . Sort and merge process . . . . . . . . Describing the sort or merge file . . . . . Describing the input to sorting or merging . Example: describing sort and input files for SORT . . . . . . . . . . . . . Coding the input procedure . . . . . . . . 213 . . 214 . . 214 . . 215 . . . 215 . 216

Part 1. Coding your program

Describing the output from sorting or merging . . Coding the output procedure . . . . . . . . Example: coding the output procedure when using DFSORT . . . . . . . . . . . . Restrictions on input and output procedures . . . Defining sort and merge data sets . . . . . . Sorting variable-length records . . . . . . . Requesting the sort or merge . . . . . . . . Setting sort or merge criteria . . . . . . . Example: sorting with input and output procedures . . . . . . . . . . . . . Choosing alternate collating sequences . . . . Sorting on windowed date fields . . . . . . Preserving the original sequence of records with equal keys . . . . . . . . . . . . . Determining whether the sort or merge was successful . . . . . . . . . . . . . . Stopping a sort or merge operation prematurely Improving sort performance with FASTSRT . . . FASTSRT requirements for JCL . . . . . . FASTSRT requirements for sort input and output files . . . . . . . . . . . . . QSAM requirements . . . . . . . . . VSAM requirements . . . . . . . . . Checking for sort errors with NOFASTSRT . . . Controlling sort behavior . . . . . . . . . Changing DFSORT defaults with control statements . . . . . . . . . . . . . Default characteristics of the IGZSRTCD data set . . . . . . . . . . . . . . . Allocating storage for sort or merge operations Allocating space for sort files . . . . . . . Using checkpoint/restart with DFSORT . . . . Sorting under CICS . . . . . . . . . . . CICS SORT application restrictions . . . . .

217 218 218 219 219 220 220 221 222 223 223 224 224 225 225 226 226 227 227 227 228 229 230 230 231 231 231 232

Chapter 13. Handling errors . . . . . . . . 233 Requesting dumps . . . . . . . . . . . 233 Handling errors in joining and splitting strings . . 234 Handling errors in arithmetic operations . . . . 234 Example: checking for division by zero . . . . 235 Handling errors in input and output operations 235 Using the end-of-file condition (AT END) . . . 238 Coding ERROR declaratives . . . . . . . 238 Using file status keys . . . . . . . . . . 239 Example: file status key . . . . . . . . . 240 Using VSAM status codes (VSAM files only) 241 Example: checking VSAM status codes . . . . 241 Coding INVALID KEY phrases . . . . . . 243 Example: FILE STATUS and INVALID KEY . . 243 Handling errors when calling programs . . . . 244 Writing routines for handling errors . . . . . . 244

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 1. Structuring your program


COBOL programs consist of four divisions: IDENTIFICATION DIVISION, ENVIRONMENT DIVISION, DATA DIVISION, and PROCEDURE DIVISION. Each division has a specific logical function. To define a program, only the IDENTIFICATION DIVISION is required. To define a COBOL class or method, you need to define some divisions differently than you do for a program.
RELATED TASKS

Identifying a program Describing the computing environment on page 7 Describing the data on page 13 Processing the data on page 19 Defining a class on page 564 Defining a class instance method on page 569 Structuring OO applications on page 603

Identifying a program
Use the IDENTIFICATION DIVISION to name a program and optionally provide other identifying information. You can use the optional AUTHOR, INSTALLATION, DATE-WRITTEN, and DATE-COMPILED paragraphs for descriptive information about a program. The data you enter in the DATE-COMPILED paragraph is replaced with the latest compilation date.
IDENTIFICATION Program-ID. Author. Installation. Date-Written. Date-Compiled. DIVISION. Helloprog. A. Programmer. Computing Laboratories. 07/30/2009. 08/30/2009.

Use the PROGRAM-ID paragraph to name your program. The program-name that you assign is used in these ways: v Other programs use that name to call your program. v The name appears in the header on each page, except the first, of the program listing that is generated when you compile the program. v If you use the NAME compiler option, the name is placed on the NAME linkage-editor or binder control statement to identify the object module that the compilation creates. Tip: Do not use program-names that start with prefixes used by IBM products. If you use program-names that start with any of the following prefixes, your CALL statements might resolve to IBM library or compiler routines rather than to your intended program: AFB AFH CBC
Copyright IBM Corp. 1991, 2009

| | | | | | |

CEE CEH CEL CEQ CEU DFH DSN EDC FOR IBM IFY IGY

IGZ ILB Tip: If a program-name is case sensitive, avoid mismatches with the name that the compiler is looking for. Verify that the appropriate setting of the PGMNAME compiler option is in effect.
RELATED TASKS

Changing the header of a source listing on page 7 Identifying a program as recursive Marking a program as callable by containing programs Setting a program to an initial state on page 7
RELATED REFERENCES

Compiler limits (Enterprise COBOL Language Reference) Conventions for program-names (Enterprise COBOL Language Reference)

Identifying a program as recursive


Code the RECURSIVE attribute on the PROGRAM-ID clause to specify that a program can be recursively reentered while a previous invocation is still active. You can code RECURSIVE only on the outermost program of a compilation unit. Neither nested subprograms nor programs that contain nested subprograms can be recursive. You must code RECURSIVE for programs that you compile with the THREAD option.
RELATED TASKS

Sharing data in recursive or multithreaded programs on page 19 Making recursive calls on page 461

Marking a program as callable by containing programs


Use the COMMON attribute in the PROGRAM-ID paragraph to specify that a program can be called by the containing program or by any program in the containing program. The COMMON program cannot be called by any program contained in itself. Only contained programs can have the COMMON attribute.

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED CONCEPTS

Nested programs on page 458

Setting a program to an initial state


Use the INITIAL attribute to specify that whenever a program is called, that program and any nested programs that it contains are to be placed in their initial state. When a program is in its initial state: v Data items that have VALUE clauses are set to the specified values. v Changed GO TO statements and PERFORM statements are in their initial states. v Non-EXTERNAL files are closed.
RELATED TASKS

Ending and reentering main programs or subprograms on page 448 Making static calls on page 450 Making dynamic calls on page 451

Changing the header of a source listing


The header on the first page of a source listing contains the identification of the compiler and the current release level, the date and time of compilation, and the page number. The following example shows these five elements:
PP 5655-S71 IBM Enterprise COBOL for z/OS 4.2.0 Date 08/30/2009 Time 15:05:19 Page 1

The header indicates the compilation platform. You can customize the header on succeeding pages of the listing by using the compiler-directing TITLE statement.
RELATED REFERENCES

TITLE statement (Enterprise COBOL Language Reference)

Describing the computing environment


In the ENVIRONMENT DIVISION of a program, you describe the aspects of the program that depend on the computing environment. Use the CONFIGURATION SECTION to specify the following items: v Computer for compiling the program (in the SOURCE-COMPUTER paragraph) v Computer for running the program (in the OBJECT-COMPUTER paragraph) v Special items such as the currency sign and symbolic characters (in the SPECIAL-NAMES paragraph) v User-defined classes (in the REPOSITORY paragraph) Use the FILE-CONTROL and I-O-CONTROL paragraphs of the INPUT-OUTPUT SECTION to: v Identify and describe the characteristics of the files in the program. v Associate your files with the external QSAM, VSAM, or HFS (hierarchical file system) data sets where they physically reside.

Chapter 1. Structuring your program

The terms file in COBOL terminology and data set or HFS file in operating-system terminology have essentially the same meaning and are used interchangeably in this information. For Customer Information Control System (CICS) and online Information Management System (IMS) message processing programs (MPP), code only the ENVIRONMENT DIVISION header and, optionally, the CONFIGURATION SECTION. CICS does not allow COBOL definition of files. IMS allows COBOL definition of files only for batch programs. v Provide information to control efficient transmission of the data records between your program and the external medium. Example: FILE-CONTROL entries
RELATED TASKS

Specifying the collating sequence on page 9 Defining symbolic characters on page 10 Defining a user-defined class on page 10 Defining files to the operating system on page 10
RELATED REFERENCES

Sections and paragraphs (Enterprise COBOL Language Reference)

Example: FILE-CONTROL entries


The following table shows example FILE-CONTROL entries for a QSAM sequential file, a VSAM indexed file, and a line-sequential file.
Table 1. FILE-CONTROL entries QSAM file SELECT PRINTFILE ASSIGN TO UPDPRINT2 ORGANIZATION IS SEQUENTIAL3 ACCESS IS SEQUENTIAL.4
1

VSAM file SELECT COMMUTER-FILE ASSIGN TO COMMUTER2 ORGANIZATION IS INDEXED3 ACCESS IS RANDOM4 RECORD KEY IS COMMUTER-KEY5 FILE STATUS IS5 COMMUTER-FILE-STATUS COMMUTER-VSAM-STATUS.
1

Line-sequential file SELECT PRINTFILE1 ASSIGN TO UPDPRINT2 ORGANIZATION IS LINE SEQUENTIAL3 ACCESS IS SEQUENTIAL.4

1. The SELECT clause chooses a file in the COBOL program to be associated with an external data set. 2. The ASSIGN clause associates the programs name for the file with the external name for the actual data file. You can define the external name with a DD statement or an environment variable. 3. The ORGANIZATION clause describes the files organization. For QSAM files, the ORGANIZATION clause is optional. 4. The ACCESS MODE clause defines the manner in which the records are made available for processing: sequential, random, or dynamic. For QSAM and line-sequential files, the ACCESS MODE clause is optional. These files always have sequential organization. 5. For VSAM files, you might have additional statements in the FILE-CONTROL paragraph depending on the type of VSAM file you use.

RELATED TASKS

Chapter 9, Processing QSAM files, on page 151 Chapter 10, Processing VSAM files, on page 179 Chapter 11, Processing line-sequential files, on page 207 Describing the computing environment on page 7

Enterprise COBOL for z/OS V4.2 Programming Guide

Specifying the collating sequence


You can use the PROGRAM COLLATING SEQUENCE clause and the ALPHABET clause of the SPECIAL-NAMES paragraph to establish the collating sequence that is used in several operations on alphanumeric items. These clauses specify the collating sequence for the following operations on alphanumeric items: v Comparisons explicitly specified in relation conditions and condition-name conditions v HIGH-VALUE and LOW-VALUE settings v SEARCH ALL v SORT and MERGE unless overridden by a COLLATING SEQUENCE phrase in the SORT or MERGE statement Example: specifying the collating sequence The sequence that you use can be based on one of these alphabets: v EBCDIC: references the collating sequence associated with the EBCDIC character set v NATIVE: references the same collating sequence as EBCDIC v STANDARD-1: references the collating sequence associated with the ASCII character set defined by ANSI INCITS X3.4, Coded Character Sets - 7-bit American National Standard Code for Information Interchange (7-bit ASCII) v STANDARD-2: references the collating sequence associated with the character set defined by ISO/IEC 646 -- Information technology -- ISO 7-bit coded character set for information interchange, International Reference Version v An alteration of the EBCDIC sequence that you define in the SPECIAL-NAMES paragraph The PROGRAM COLLATING SEQUENCE clause does not affect comparisons that involve national or DBCS operands.
RELATED TASKS

Choosing alternate collating sequences on page 223 Comparing national (UTF-16) data on page 139

Example: specifying the collating sequence


The following example shows the ENVIRONMENT DIVISION coding that you can use to specify a collating sequence in which uppercase and lowercase letters are similarly handled in comparisons and in sorting and merging. When you change the EBCDIC sequence in the SPECIAL-NAMES paragraph, the overall collating sequence is affected, not just the collating sequence of the characters that are included in the SPECIAL-NAMES paragraph.
IDENTIFICATION DIVISION. . . . ENVIRONMENT DIVISION. CONFIGURATION SECTION. Source-Computer. IBM-390. Object-Computer. IBM-390. Program Collating Sequence Special-Sequence. Special-Names. Alphabet Special-Sequence Is
Chapter 1. Structuring your program

"A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
RELATED TASKS

Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also Also

"a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z".

Specifying the collating sequence on page 9

Defining symbolic characters


Use the SYMBOLIC CHARACTERS clause to give symbolic names to any character of the specified alphabet. Use ordinal position to identify the character, where position 1 corresponds to character X00. For example, to give a name to the backspace character (X16 in the EBCDIC alphabet), code:
SYMBOLIC CHARACTERS BACKSPACE IS 23

Defining a user-defined class


Use the CLASS clause to give a name to a set of characters that you list in the clause. For example, name the set of digits by coding the following clause:
CLASS DIGIT IS "0" THROUGH "9"

You can reference the class-name only in a class condition. (This user-defined class is not the same as an object-oriented class.)

Defining files to the operating system


For all files that you process in your COBOL program, you need to define the files to the operating system with an appropriate system data definition. Depending on the operating system, this system data definition can take any of the following forms: v DD statement for MVS JCL.

10

Enterprise COBOL for z/OS V4.2 Programming Guide

v ALLOCATE command under TSO. v Environment variable for z/OS or UNIX. The contents can define either an MVS data set or a file in the HFS (hierarchical file system). The following examples show the relationship of a FILE-CONTROL entry to the system data definition and to the FD entry in the FILE SECTION: v JCL DD statement:
(1) //OUTFILE /* DD DSNAME=MY.OUT171,UNIT=SYSDA,SPACE=(TRK,(50,5))

v Environment variable (export command):


(1) export OUTFILE=DSN(MY.OUT171),UNIT(SYSDA),SPACE(TRK,(50,5))

v COBOL code:
ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CARPOOL ASSIGN TO OUTFILE (1) ORGANIZATION IS SEQUENTIAL. . . . DATA DIVISION. FILE SECTION. FD CARPOOL (2) LABEL RECORD STANDARD BLOCK CONTAINS 0 CHARACTERS RECORD CONTAINS 80 CHARACTERS

(1)

The assignment-name in the ASSIGN clause points to the ddname OUTFILE in the DD statement or the environment variable OUTFILE in the export command: v //OUTFILE DD DSNAME=OUT171 . . ., or v export OUTFILE= . . . When you specify a file file-name in a FILE-CONTROL entry, you must describe the file in an FD entry:
SELECT CARPOOL . . . FD CARPOOL

(2)

RELATED TASKS

Optimizing buffer and device space on page 12


RELATED REFERENCES

FILE SECTION entries on page 14 File section (Enterprise COBOL Language Reference)

Varying the input or output file at run time


The file-name that you code in a SELECT clause is used as a constant throughout your COBOL program, but you can associate the name of the file with a different actual file at run time. Changing a file-name in a COBOL program would require changing the input statements and output statements and recompiling the program. Alternatively, you can change the DSNAME value in the DD statement or the DSN or PATH value in the export command to use a different file at run time.

Chapter 1. Structuring your program

11

Environment variable values that are in effect at the time of the OPEN statement are used for associating COBOL file-names to the system file-names (including any path specifications). The name that you use in the assignment-name of the ASSIGN clause must be the same as the ddname in the DD statement or the environment variable in the export command. The file-name that you use in the SELECT clause (such as SELECT MASTER) must be the same as in the FD file-name entry. Two files should not use the same ddname or environment variable name in their SELECT clauses; otherwise, results could be unpredictable. For example, if DISPLAY output is directed to SYSOUT, do not use SYSOUT as the ddname or environment variable name in the SELECT clause for a file. Example: using different input files: This example shows that you use the same COBOL program to access different files by coding a DD statement or an export command before the programs runs. Consider a COBOL program that contains the following SELECT clause:
SELECT MASTER ASSIGN TO DA-3330-S-MASTERA

Assume the three possible input files are MASTER1, MASTER2, and MASTER3. Before running the program, code one of the following DD statements in the job step that calls for program execution, or issue one of the following export commands from the same shell from which you run the program:
//MASTERA DD DSNAME=MY.MASTER1,. . . export MASTERA=DSN(MY.MASTER1),. . . //MASTERA DD DSNAME=MY.MASTER2,. . . export MASTERA=DSN(MY.MASTER2),. . . //MASTERA DD DSNAME=MY.MASTER3,. . . export MASTERA=DSN(MY.MASTER3),. . .

Any reference in the program to MASTER will therefore be a reference to the file currently assigned to the ddname or environment-variable name MASTERA. Notice that in this example, you cannot use the PATH(path) form of the export command to reference a line-sequential file in the HFS, because you cannot specify an organization field (S- or AS-) with a line-sequential file.

Optimizing buffer and device space


Use the APPLY WRITE-ONLY clause to make optimum use of buffer and device space when you create a sequential file with blocked variable-length records. With APPLY WRITE-ONLY specified, a buffer is truncated only when the next record does not fit in the unused portion of the buffer. Without APPLY WRITE-ONLY specified, a buffer is truncated when it does not have enough space for a maximum-size record. The APPLY WRITE-ONLY clause has meaning only for sequential files that have variable-length records and are blocked.

12

Enterprise COBOL for z/OS V4.2 Programming Guide

The AWO compiler option applies an implicit APPLY WRITE-ONLY clause to all eligible files. The NOAWO compiler option has no effect on files that have the APPLY WRITE-ONLY clause specified. The APPLY WRITE-ONLY clause takes precedence over the NOAWO compiler option. The APPLY-WRITE ONLY clause can cause input files to use a record area rather than process the data in the buffer. This use might affect the processing of both input files and output files.
RELATED REFERENCES

AWO on page 307

Describing the data


Define the characteristics of your data, and group your data definitions into one or more of the sections in the DATA DIVISION. You can use these sections for defining the following types of data: v Data used in input-output operations: FILE SECTION v Data developed for internal processing: To have storage be statically allocated and exist for the life of the run unit: WORKING-STORAGE SECTION To have storage be allocated each time a program is entered, and deallocated on return from the program: LOCAL-STORAGE SECTION v Data from another program: LINKAGE SECTION The Enterprise COBOL compiler limits the maximum size of DATA DIVISION elements. For details, see the related reference about compiler limits below.
RELATED CONCEPTS

Comparison of WORKING-STORAGE and LOCAL-STORAGE on page 16


RELATED TASKS

Using data in input and output operations Using data from another program on page 18
RELATED REFERENCES

Compiler limits (Enterprise COBOL Language Reference)

Using data in input and output operations


Define the data that you use in input and output operations in the FILE SECTION. Provide the following information about the data: v Name the input and output files that the program will use. Use the FD entry to give names to the files that the input-output statements in the PROCEDURE DIVISION can refer to. Data items defined in the FILE SECTION are not available to PROCEDURE DIVISION statements until the file has been successfully opened. v In the record description that follows the FD entry, describe the fields of the records in the file: You can code a level-01 description of the entire record, and then in the WORKING-STORAGE SECTION code a working copy that describes the fields of the
Chapter 1. Structuring your program

13

record in more detail. Use the READ INTO statement to bring the records into WORKING-STORAGE. Processing occurs on the copy of data in WORKING-STORAGE. A WRITE FROM statement writes processed data into the record area defined in the FILE SECTION. The record-name established is the object of WRITE and REWRITE statements. For QSAM files only, you can set the record format in the RECORDING MODE clause. If you omit the RECORDING MODE clause, the compiler determines the record format based on the RECORD clause and on the level-01 record descriptions. For QSAM files, you can set a blocking factor for the file in the BLOCK CONTAINS clause. If you omit the BLOCK CONTAINS clause, the file defaults to unblocked. However, you can override this with z/OS data management facilities (including a DD file job-control statement). For line-sequential files, you can set a blocking factor for the file in the BLOCK CONTAINS clause. When you code BLOCK CONTAINS 1 RECORDS, or BLOCK CONTAINS n CHARACTERS, where n is the length of one logical record in bytes, WRITE statements result in the record being transferred immediately to the file rather than being buffered. This technique is useful when you want each record written immediately, such as to an error log. Programs in the same run unit can share, or have access to, common files. The method for doing this depends on whether the programs are part of a nested (contained) structure or are separately compiled (including programs compiled as part of a batch sequence). You can use the EXTERNAL clause for separately compiled programs. A file that is defined as EXTERNAL can be referenced by any program in the run unit that describes the file. You can use the GLOBAL clause for programs in a nested, or contained, structure. If a program contains another program (directly or indirectly), both programs can access a common file by referencing a GLOBAL file-name.
RELATED CONCEPTS

Nested programs on page 458


RELATED TASKS

Sharing files between programs (external files) on page 475


RELATED REFERENCES

FILE SECTION entries

FILE SECTION entries


The entries that you can use in the FILE SECTION are summarized in the table below.
Table 2. FILE SECTION entries Clause FD To define The file-name to be referred to in PROCEDURE DIVISION input-output statements (OPEN, CLOSE, READ, also START and DELETE for VSAM) Notes Must match file-name in the SELECT clause. file-name is associated with a ddname through the assignment-name.

14

Enterprise COBOL for z/OS V4.2 Programming Guide

Table 2. FILE SECTION entries (continued) Clause BLOCK CONTAINS To define Size of physical records Notes If the CHARACTERS phrase is specified, size indicates the number of bytes in a record regardless of the USAGE of the data items in the record. QSAM: If provided, must match information on JCL or data-set label. If specified as BLOCK CONTAINS 0, or not provided, the system determines the optimal block size for you. Line sequential: Can be specified to control buffering for WRITE statements. VSAM: Syntax-checked, but has no effect on execution. RECORD CONTAINS n Size of logical records (fixed length) Integer size indicates the number of bytes in a record regardless of the USAGE of the data items in the record. If the clause is provided, it must match information on JCL or data-set label. If n is equal to 0, LRECL must be coded on JCL or data-set label. Integer size or sizes, if specified, indicate the number of bytes in a record regardless of the USAGE of the data items in the record. If the clause is provided, it must match information on JCL or data-set label; compiler checks that record descriptions match. The integer sizes indicate the number of bytes in a record regardless of the USAGE of the data items in the record. If the clause is provided, it must match information on JCL or data-set label; compiler checks that record descriptions match. VSAM: Handled as comments QSAM: Handled as comments QSAM: Handled as comments

RECORD IS VARYING

Size of logical records (variable length)

RECORD CONTAINS n TO m

Size of logical records (variable length)

LABEL RECORDS STANDARD OMITTED data-name VALUE OF

Labels for QSAM files Labels exist Labels do not exist

Labels defined by the user QSAM: Allowed for (optional) tape or disk An item in the label records associated with file Names of records associated with file Depth of logical page Comments only

DATA RECORDS LINAGE

Comments only QSAM only

Chapter 1. Structuring your program

15

Table 2. FILE SECTION entries (continued) Clause CODE-SET To define ASCII or EBCDIC files Notes QSAM only. When an ASCII file is identified with the CODE-SET clause, the corresponding DD statement might need to have DCB=(OPTCD=Q. . .) or DCB=(RECFM=D. . .) coded if the file was not created using VS COBOL II, COBOL for OS/390 & VM, or IBM Enterprise COBOL for z/OS. RECORDING MODE Physical record description QSAM only

RELATED CONCEPTS

Labels for QSAM files on page 174


RELATED REFERENCES

File section (Enterprise COBOL Language Reference)

Comparison of WORKING-STORAGE and LOCAL-STORAGE


How data items are allocated and initialized varies depending on whether the items are in the WORKING-STORAGE SECTION or LOCAL-STORAGE SECTION. WORKING-STORAGE for programs is allocated at the start of the run unit. Any data items that have VALUE clauses are initialized to the appropriate value at that time. For the duration of the run unit, WORKING-STORAGE items persist in their last-used state. Exceptions are: v A program with INITIAL specified in the PROGRAM-ID paragraph In this case, WORKING-STORAGE data items are reinitialized each time that the program is entered. v A subprogram that is dynamically called and then canceled In this case, WORKING-STORAGE data items are reinitialized on the first reentry into the program following the CANCEL. WORKING-STORAGE is deallocated at the termination of the run unit. See the related tasks for information about WORKING-STORAGE in COBOL class definitions. A separate copy of LOCAL-STORAGE data is allocated for each call of a program or invocation of a method, and is freed on return from the program or method. If you specify a VALUE clause for a LOCAL-STORAGE item, the item is initialized to that value on each call or invocation. If a VALUE clause is not specified, the initial value of the item is undefined. Threading: Each invocation of a program that runs simultaneously on multiple threads shares access to a single copy of WORKING-STORAGE data. Each invocation has a separate copy of LOCAL-STORAGE data. Example: storage sections on page 17

16

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED TASKS

Ending and reentering main programs or subprograms on page 448 Chapter 27, Preparing COBOL programs for multithreading, on page 493 WORKING-STORAGE SECTION for defining class instance data on page 568
RELATED REFERENCES

Working-storage section (Enterprise COBOL Language Reference) Local-storage section (Enterprise COBOL Language Reference)

Example: storage sections


The following is an example of a recursive program that uses both WORKING-STORAGE and LOCAL-STORAGE.
CBL pgmn(lu) ********************************* * Recursive Program - Factorials ********************************* IDENTIFICATION DIVISION. Program-Id. factorial recursive. ENVIRONMENT DIVISION. DATA DIVISION. Working-Storage Section. 01 numb pic 9(4) value 5. 01 fact pic 9(8) value 0. Local-Storage Section. 01 num pic 9(4). PROCEDURE DIVISION. move numb to num. if numb = 0 move 1 to fact else subtract 1 from numb call 'factorial' multiply num by fact end-if. display num '! = ' fact. goback. End Program factorial.

The program produces the following output:


0000! 0001! 0002! 0003! 0004! 0005! = = = = = = 00000001 00000001 00000002 00000006 00000024 00000120

The following tables show the changing values of the data items in LOCAL-STORAGE and WORKING-STORAGE in the successive recursive calls of the program, and in the ensuing gobacks. During the gobacks, fact progressively accumulates the value of 5! (five factorial).
Recursive calls Main 1 2 3 Value for num in LOCAL-STORAGE 5 4 3 2 Value for numb in WORKING-STORAGE 5 4 3 2 Value for fact in WORKING-STORAGE 0 0 0 0

Chapter 1. Structuring your program

17

Recursive calls 4 5

Value for num in LOCAL-STORAGE 1 0

Value for numb in WORKING-STORAGE 1 0

Value for fact in WORKING-STORAGE 0 0

Gobacks 5 4 3 2 1 Main

Value for num in LOCAL-STORAGE 0 1 2 3 4 5

Value for numb in WORKING-STORAGE 0 0 0 0 0 0

Value for fact in WORKING-STORAGE 1 1 2 6 24 120

RELATED CONCEPTS

Comparison of WORKING-STORAGE and LOCAL-STORAGE on page 16

Using data from another program


How you share data depends on the type of program. You share data differently in programs that are separately compiled than you do for programs that are nested or for programs that are recursive or multithreaded.
RELATED TASKS

Sharing data in separately compiled programs Sharing data in nested programs Sharing data in recursive or multithreaded programs on page 19 Passing data on page 465

Sharing data in separately compiled programs


Many applications consist of separately compiled programs that call and pass data to one another. Use the LINKAGE SECTION in the called program to describe the data passed from another program. In the calling program, use a CALL . . . USING or INVOKE . . . USING statement to pass the data.
RELATED TASKS

Passing data on page 465

Sharing data in nested programs


Some applications consist of nested programs, that is, programs that are contained in other programs. Level-01 data items can include the GLOBAL attribute. This attribute allows any nested program that includes the declarations to access these data items.

18

Enterprise COBOL for z/OS V4.2 Programming Guide

A nested program can also access data items in a sibling program (one at the same nesting level in the same containing program) that is declared with the COMMON attribute.
RELATED CONCEPTS

Nested programs on page 458

Sharing data in recursive or multithreaded programs


If your program has the RECURSIVE attribute or is compiled with the THREAD compiler option, data that is defined in the LINKAGE SECTION is not accessible on subsequent invocations of the program. To address a record in the LINKAGE SECTION, use either of these techniques: v Pass an argument to the program and specify the record in an appropriate position in the USING phrase in the program. v Use the format-5 SET statement. If your program has the RECURSIVE attribute or is compiled with the THREAD compiler option, the address of the record is valid for a particular instance of the program invocation. The address of the record in another execution instance of the same program must be reestablished for that execution instance. Unpredictable results will occur if you refer to a data item for which the address has not been established.
RELATED CONCEPTS

Multithreading on page 494


RELATED TASKS

Making recursive calls on page 461 Processing files with multithreading on page 496
RELATED REFERENCES

THREAD on page 352 SET statement (Enterprise COBOL Language Reference)

Processing the data


In the PROCEDURE DIVISION of a program, you code the executable statements that process the data that you defined in the other divisions. The PROCEDURE DIVISION contains one or two headers and the logic of your program. The PROCEDURE DIVISION begins with the division header and a procedure-name header. The division header for a program can simply be:
PROCEDURE DIVISION.

You can code the division header to receive parameters by using the USING phrase, or to return a value by using the RETURNING phrase. To receive an argument that was passed by reference (the default) or by content, code the division header for a program in either of these ways:
PROCEDURE DIVISION USING dataname PROCEDURE DIVISION USING BY REFERENCE dataname

Be sure to define dataname in the LINKAGE SECTION of the DATA DIVISION.


Chapter 1. Structuring your program

19

To receive a parameter that was passed by value, code the division header for a program as follows:
PROCEDURE DIVISION USING BY VALUE dataname

To return a value as a result, code the division header as follows:


PROCEDURE DIVISION RETURNING dataname2

You can also combine USING and RETURNING in a PROCEDURE DIVISION header:
PROCEDURE DIVISION USING dataname RETURNING dataname2

Be sure to define dataname and dataname2 in the LINKAGE SECTION.


RELATED CONCEPTS

How logic is divided in the PROCEDURE DIVISION


RELATED TASKS

Eliminating repetitive coding on page 679


RELATED REFERENCES

The procedure division header (Enterprise COBOL Language Reference) The USING phrase (Enterprise COBOL Language Reference) CALL statement (Enterprise COBOL Language Reference)

How logic is divided in the PROCEDURE DIVISION


The PROCEDURE DIVISION of a program is divided into sections and paragraphs, which contain sentences, statements, and phrases. Section Logical subdivision of your processing logic. A section has a section header and is optionally followed by one or more paragraphs. A section can be the subject of a PERFORM statement. One type of section is for declaratives. Paragraph Subdivision of a section, procedure, or program. A paragraph has a name followed by a period and zero or more sentences. A paragraph can be the subject of a statement. Sentence Series of one or more COBOL statements that ends with a period. Statement Performs a defined step of COBOL processing, such as adding two numbers. A statement is a valid combination of words, and begins with a COBOL verb. Statements are imperative (indicating unconditional action), conditional, or compiler-directing. Using explicit scope terminators instead of periods to show the logical end of a statement is preferred. Phrase A subdivision of a statement.
RELATED CONCEPTS

Compiler-directing statements on page 22

20

Enterprise COBOL for z/OS V4.2 Programming Guide

Scope terminators on page 22 Imperative statements Conditional statements Declaratives on page 23


RELATED REFERENCES

PROCEDURE DIVISION structure (Enterprise COBOL Language Reference)

Imperative statements
An imperative statement (such as ADD, MOVE, INVOKE, or CLOSE) indicates an unconditional action to be taken. You can end an imperative statement with an implicit or explicit scope terminator. A conditional statement that ends with an explicit scope terminator becomes an imperative statement called a delimited scope statement. Only imperative statements (or delimited scope statements) can be nested.
RELATED CONCEPTS

Conditional statements Scope terminators on page 22

Conditional statements
A conditional statement is either a simple conditional statement (IF, EVALUATE, SEARCH) or a conditional statement made up of an imperative statement that includes a conditional phrase or option. You can end a conditional statement with an implicit or explicit scope terminator. If you end a conditional statement explicitly, it becomes a delimited scope statement (which is an imperative statement). You can use a delimited scope statement in these ways: v To delimit the range of operation for a COBOL conditional statement and to explicitly show the levels of nesting For example, use an END-IF phrase instead of a period to end the scope of an IF statement within a nested IF. v To code a conditional statement where the COBOL syntax calls for an imperative statement For example, code a conditional statement as the object of an inline PERFORM:
PERFORM UNTIL TRANSACTION-EOF PERFORM 200-EDIT-UPDATE-TRANSACTION IF NO-ERRORS PERFORM 300-UPDATE-COMMUTER-RECORD ELSE PERFORM 400-PRINT-TRANSACTION-ERRORS END-IF READ UPDATE-TRANSACTION-FILE INTO WS-TRANSACTION-RECORD AT END SET TRANSACTION-EOF TO TRUE END-READ END-PERFORM

An explicit scope terminator is required for the inline PERFORM statement, but it is not valid for the out-of-line PERFORM statement. For additional program control, you can use the NOT phrase with conditional statements. For example, you can provide instructions to be performed when a
Chapter 1. Structuring your program

21

particular exception does not occur, such as NOT ON SIZE ERROR. The NOT phrase cannot be used with the ON OVERFLOW phrase of the CALL statement, but it can be used with the ON EXCEPTION phrase. Do not nest conditional statements. Nested statements must be imperative statements (or delimited scope statements) and must follow the rules for imperative statements. The following statements are examples of conditional statements if they are coded without scope terminators: v Arithmetic statement with ON SIZE ERROR v v v v Data-manipulation statements with ON OVERFLOW CALL statements with ON OVERFLOW I/O statements with INVALID KEY, AT END, or AT END-OF-PAGE RETURN with AT END

RELATED CONCEPTS

Imperative statements on page 21 Scope terminators


RELATED TASKS

Selecting program actions on page 89


RELATED REFERENCES

Conditional statements (Enterprise COBOL Language Reference)

Compiler-directing statements
A compiler-directing statement causes the compiler to take specific action about the program structure, COPY processing, listing control, or control flow. A compiler-directing statement is not part of the program logic.
RELATED REFERENCES

Chapter 18, Compiler-directing statements, on page 363 Compiler-directing statements (Enterprise COBOL Language Reference)

Scope terminators
A scope terminator ends a verb or statement. Scope terminators can be explicit or implicit. Explicit scope terminators end a verb without ending a sentence. They consist of END followed by a hyphen and the name of the verb being terminated, such as END-IF. An implicit scope terminator is a period (.) that ends the scope of all previous statements not yet ended. Each of the two periods in the following program fragment ends an IF statement, making the code equivalent to the code after it that instead uses explicit scope terminators:
IF ITEM = "A" DISPLAY "THE VALUE OF ITEM IS " ITEM ADD 1 TO TOTAL MOVE "C" TO ITEM DISPLAY "THE VALUE OF ITEM IS NOW " ITEM. IF ITEM = "B" ADD 2 TO TOTAL.

22

Enterprise COBOL for z/OS V4.2 Programming Guide

IF ITEM = "A" DISPLAY "THE VALUE OF ITEM IS " ITEM ADD 1 TO TOTAL MOVE "C" TO ITEM DISPLAY "THE VALUE OF ITEM IS NOW " ITEM END-IF IF ITEM = "B" ADD 2 TO TOTAL END-IF

If you use implicit terminators, the end of statements can be unclear. As a result, you might end statements unintentionally, changing your programs logic. Explicit scope terminators make a program easier to understand and prevent unintentional ending of statements. For example, in the program fragment below, changing the location of the first period in the first implicit scope example changes the meaning of the code:
IF ITEM = "A" DISPLAY "VALUE OF ITEM IS " ITEM ADD 1 TO TOTAL. MOVE "C" TO ITEM DISPLAY " VALUE OF ITEM IS NOW " ITEM IF ITEM = "B" ADD 2 TO TOTAL.

The MOVE statement and the DISPLAY statement after it are performed regardless of the value of ITEM, despite what the indentation indicates, because the first period terminates the IF statement. For improved program clarity and to avoid unintentional ending of statements, use explicit scope terminators, especially within paragraphs. Use implicit scope terminators only at the end of a paragraph or the end of a program. Be careful when coding an explicit scope terminator for an imperative statement that is nested within a conditional statement. Ensure that the scope terminator is paired with the statement for which it was intended. In the following example, the scope terminator will be paired with the second READ statement, though the programmer intended it to be paired with the first.
READ FILE1 AT END MOVE A TO B READ FILE2 END-READ

To ensure that the explicit scope terminator is paired with the intended statement, the preceding example can be recoded in this way:
READ FILE1 AT END MOVE A TO B READ FILE2 END-READ END-READ
RELATED CONCEPTS

Conditional statements on page 21 Imperative statements on page 21

Declaratives
Declaratives provide one or more special-purpose sections that are executed when an exception condition occurs.
Chapter 1. Structuring your program

23

Start each declarative section with a USE statement that identifies the function of the section. In the procedures, specify the actions to be taken when the condition occurs.
RELATED TASKS

Finding and handling input-output errors on page 369


RELATED REFERENCES

Declaratives (Enterprise COBOL Language Reference)

24

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 2. Using data


This information is intended to help non-COBOL programmers relate terms for data used in other programming languages to COBOL terms. It introduces COBOL fundamentals for variables, structures, literals, and constants; assigning and displaying values; intrinsic (built-in) functions, and tables (arrays) and pointers.
RELATED CONCEPTS

Storage and its addressability on page 42


RELATED TASKS

Using variables, structures, literals, and constants Assigning values to data items on page 29 Displaying values on a screen or in a file (DISPLAY) on page 38 Using intrinsic functions (built-in functions) on page 40 Using tables (arrays) and pointers on page 41 Chapter 7, Processing data in an international environment, on page 121

Using variables, structures, literals, and constants


Most high-level programming languages share the concept of data being represented as variables, structures (group items), literals, or constants. The data in a COBOL program can be alphabetic, alphanumeric, double-byte character set (DBCS), national, or numeric. You can also define index-names and data items described as USAGE POINTER, USAGE FUNCTION-POINTER, USAGE PROCEDURE-POINTER, or USAGE OBJECT REFERENCE. You place all data definitions in the DATA DIVISION of your program.
RELATED TASKS

Using Using Using Using Using

variables data items and group items on page 26 literals on page 27 constants on page 28 figurative constants on page 28

RELATED REFERENCES

Classes and categories of data (Enterprise COBOL Language Reference)

Using variables
A variable is a data item whose value can change during a program. The value is restricted, however, to the data type that you define when you specify a name and a length for the data item. For example, if a customer name is an alphanumeric data item in your program, you could define and use the customer name as shown below:
Data Division. 01 Customer-Name 01 Original-Customer-Name Pic X(20). Pic X(20).

Copyright IBM Corp. 1991, 2009

25

. . . Procedure Division. Move Customer-Name to Original-Customer-Name . . .

You could instead declare the customer names above as national data items by specifying their PICTURE clauses as Pic N(20) and specifying the USAGE NATIONAL clause for the items. National data items are represented in Unicode UTF-16, in which most characters are represented in 2 bytes of storage.
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125


RELATED TASKS

Using national data (Unicode) in COBOL on page 126


RELATED REFERENCES

NSYMBOL on page 331 Storage of character data on page 133 PICTURE clause (Enterprise COBOL Language Reference)

Using data items and group items


Related data items can be parts of a hierarchical data structure. A data item that does not have subordinate data items is called an elementary item. A data item that is composed of one or more subordinate data items is called a group item. A record can be either an elementary item or a group item. A group item can be either an alphanumeric group item or a national group item. For example, Customer-Record below is an alphanumeric group item that is composed of two subordinate alphanumeric group items (Customer-Name and Part-Order), each of which contains elementary data items. These groups items implicitly have USAGE DISPLAY. You can refer to an entire group item or to parts of a group item in MOVE statements in the PROCEDURE DIVISION as shown below:
Data Division. File Section. FD Customer-File Record Contains 45 Characters. 01 Customer-Record. 05 Customer-Name. 10 Last-Name Pic x(17). 10 Filler Pic x. 10 Initials Pic xx. 05 Part-Order. 10 Part-Name Pic x(15). 10 Part-Color Pic x(10). Working-Storage Section. 01 Orig-Customer-Name. 05 Surname Pic x(17). 05 Initials Pic x(3). 01 Inventory-Part-Name Pic x(15). . . . Procedure Division. Move Customer-Name to Orig-Customer-Name Move Part-Name to Inventory-Part-Name . . .

You could instead define Customer-Record as a national group item that is composed of two subordinate national group items by changing the declarations in

26

Enterprise COBOL for z/OS V4.2 Programming Guide

the DATA DIVISION as shown below. National group items behave in the same way as elementary category national data items in most operations. The GROUP-USAGE NATIONAL clause indicates that a group item and any group items subordinate to it are national groups. Subordinate elementary items in a national group must be explicitly or implicitly described as USAGE NATIONAL.
Data Division. File Section. FD Customer-File Record Contains 90 Characters. 01 Customer-Record Group-Usage National. 05 Customer-Name. 10 Last-Name Pic n(17). 10 Filler Pic n. 10 Initials Pic nn. 05 Part-Order. 10 Part-Name Pic n(15). 10 Part-Color Pic n(10). Working-Storage Section. 01 Orig-Customer-Name Group-Usage National. 05 Surname Pic n(17). 05 Initials Pic n(3). 01 Inventory-Part-Name Pic n(15) Usage National. . . . Procedure Division. Move Customer-Name to Orig-Customer-Name Move Part-Name to Inventory-Part-Name . . .

In the example above, the group items could instead specify the USAGE NATIONAL clause at the group level. A USAGE clause at the group level applies to each elementary data item in a group (and thus serves as a convenient shorthand notation). However, a group that specifies the USAGE NATIONAL clause is not a national group despite the representation of the elementary items within the group. Groups that specify the USAGE clause are alphanumeric groups and behave in many operations, such as moves and compares, like elementary data items of USAGE DISPLAY (except that no editing or conversion of data occurs).
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125 National groups on page 129
RELATED TASKS

Using national data (Unicode) in COBOL on page 126 Using national groups on page 130
RELATED REFERENCES

FILE SECTION entries on page 14 Storage of character data on page 133 Classes and categories of group items (Enterprise COBOL Language Reference) PICTURE clause (Enterprise COBOL Language Reference) MOVE statement (Enterprise COBOL Language Reference) USAGE clause (Enterprise COBOL Language Reference)

Using literals
A literal is a character string whose value is given by the characters themselves. If you know the value you want a data item to have, you can use a literal representation of the data value in the PROCEDURE DIVISION.

Chapter 2. Using data

27

You do not need to declare a data item for the value nor refer to it by using a data-name. For example, you can prepare an error message for an output file by moving an alphanumeric literal:
Move "Name is not valid" To Customer-Name

You can compare a data item to a specific integer value by using a numeric literal. In the example below, "Name is not valid" is an alphanumeric literal, and 03519 is a numeric literal:
01 Part-number Pic 9(5). . . . If Part-number = 03519 then display "Part number was found"

You can use the opening delimiter N" or N' to designate a national literal if the NSYMBOL(NATIONAL) compiler option is in effect, or to designate a DBCS literal if the NSYMBOL(DBCS) compiler option is in effect. You can use the opening delimiter NX" or NX' to designate national literals in hexadecimal notation (regardless of the setting of the NSYMBOL compiler option). Each group of four hexadecimal digits designates a single national character.
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125


RELATED TASKS

Using national literals on page 127 Using DBCS literals on page 142
RELATED REFERENCES

NSYMBOL on page 331 Literals (Enterprise COBOL Language Reference)

Using constants
A constant is a data item that has only one value. COBOL does not define a construct for constants. However, you can define a data item with an initial value by coding a VALUE clause in the data description (instead of coding an INITIALIZE statement).
Data Division. 01 Report-Header . . . 01 Interest pic x(50) value "Company Sales Report".

pic 9v9999 value 1.0265.

The example above initializes an alphanumeric and a numeric data item. You can likewise use a VALUE clause in defining a national or DBCS constant.
RELATED TASKS

Using national data (Unicode) in COBOL on page 126 Coding for use of DBCS support on page 141

Using figurative constants


Certain commonly used constants and literals are available as reserved words called figurative constants: ZERO, SPACE, HIGH-VALUE, LOW-VALUE, QUOTE, NULL, and ALL literal. Because they represent fixed values, figurative constants do not require a data definition.

28

Enterprise COBOL for z/OS V4.2 Programming Guide

For example:
Move Spaces To Report-Header
RELATED TASKS

Using national-character figurative constants on page 128 Coding for use of DBCS support on page 141
RELATED REFERENCES

Figurative constants (Enterprise COBOL Language Reference)

Assigning values to data items


After you have defined a data item, you can assign a value to it at any time. Assignment takes many forms in COBOL, depending on what you want to do.
Table 3. Assignment to data items in a program What you want to do Assign values to a data item or large data area. How to do it Use one of these ways: v INITIALIZE statement v MOVE statement v STRING or UNSTRING statement v VALUE clause (to set data items to the values you want them to have when the program is in initial state) Assign the results of arithmetic. Use COMPUTE, ADD, SUBTRACT, MULTIPLY, or DIVIDE statements.

Examine or replace characters or groups of characters in a data Use the INSPECT statement. item. Receive values from a file. Receive values from a system input device or a file. Establish a constant. Use the READ (or READ INTO) statement. Use the ACCEPT statement. Use the VALUE clause in the definition of the data item, and do not use the data item as a receiver. Such an item is in effect a constant even though the compiler does not enforce read-only constants. Use the SET statement.

One of these actions: v Place a value associated with a table element in an index. v Set the status of an external switch to ON or OFF. v Move data to a condition-name to make the condition true. v Set a POINTER, PROCEDURE-POINTER, or FUNCTION-POINTER data item to an address. v Associate an OBJECT REFERENCE data item with an object instance.

Examples: initializing data items on page 30


RELATED TASKS

Initializing a structure (INITIALIZE) on page 32 Assigning values to elementary data items (MOVE) on page 34 Assigning values to group data items (MOVE) on page 35 Assigning input from a screen or file (ACCEPT) on page 37 Joining data items (STRING) on page 101
Chapter 2. Using data

29

Splitting data items (UNSTRING) on page 103 Assigning arithmetic results (MOVE or COMPUTE) on page 36 Tallying and replacing data items (INSPECT) on page 111 Chapter 7, Processing data in an international environment, on page 121

Examples: initializing data items


The following examples show how you can initialize many kinds of data items, including alphanumeric, national-edited, and numeric-edited data items, by using INITIALIZE statements. An INITIALIZE statement is functionally equivalent to one or more MOVE statements. The related tasks about initializing show how you can use an INITIALIZE statement on a group item to conveniently initialize all the subordinate data items that are in a given data category. Initializing a data item to blanks or zeros:
INITIALIZE identifier-1 identifier-1 PICTURE 9(5) X(5) N(3) 99XX9 XXBX/XX **99.9CR A(5) +99.99E+99 identifier-1 before 12345 AB123 0041004200312 12AB3 ABbC/DE 1234.5CR ABCDE +12.34E+02 identifier-1 after 00000 bbbbb1 0020002000203 bbbbb1 bbbb/bb1 **00.0bb1 bbbbb1 +00.00E+00

1. The symbol b represents a blank space. 2. Hexadecimal representation of the national (UTF-16) characters AB1. The example assumes that identifier-1 has Usage National. 3. Hexadecimal representation of the national (UTF-16) characters (three blank spaces). Note that if identifier-1 were not defined as Usage National, and if NSYMBOL(DBCS) were in effect, INITIALIZE would instead store DBCS spaces (4040) into identifier-1.

Initializing an alphanumeric data item:


01 ALPHANUMERIC-1 PIC X VALUE "y". 01 ALPHANUMERIC-3 PIC X(1) VALUE "A". . . . INITIALIZE ALPHANUMERIC-1 REPLACING ALPHANUMERIC DATA BY ALPHANUMERIC-3 ALPHANUMERIC-3 A ALPHANUMERIC-1 before y ALPHANUMERIC-1 after A

Initializing an alphanumeric right-justified data item:


01 ANJUST PIC X(8) VALUE SPACES JUSTIFIED RIGHT. 01 ALPHABETIC-1 PIC A(4) VALUE "ABCD". . . . INITIALIZE ANJUST REPLACING ALPHANUMERIC DATA BY ALPHABETIC-1

30

Enterprise COBOL for z/OS V4.2 Programming Guide

ALPHABETIC-1 ABCD

ANJUST before bbbbbbbb


1

ANJUST after bbbbABCD1

1. The symbol b represents a blank space.

Initializing an alphanumeric-edited data item:


01 ALPHANUM-EDIT-1 PIC XXBX/XXX VALUE "ABbC/DEF". 01 ALPHANUM-EDIT-3 PIC X/BB VALUE "M/bb". . . . INITIALIZE ALPHANUM-EDIT-1 REPLACING ALPHANUMERIC-EDITED DATA BY ALPHANUM-EDIT-3 ALPHANUM-EDIT-3 M/bb1 ALPHANUM-EDIT-1 before ABbC/DEF1 ALPHANUM-EDIT-1 after M/bb/bbb1

1. The symbol b represents a blank space.

Initializing a national data item:


01 NATIONAL-1 PIC NN USAGE NATIONAL VALUE N"AB". 01 NATIONAL-3 PIC NN USAGE NATIONAL VALUE N"CD". . . . INITIALIZE NATIONAL-1 REPLACING NATIONAL DATA BY NATIONAL-3 NATIONAL-3 00430044
1

NATIONAL-1 before 00410042


2

NATIONAL-1 after 004300441

1. Hexadecimal representation of the national characters CD 2. Hexadecimal representation of the national characters AB

Initializing a national-edited data item:


01 NATL-EDIT-1 PIC 0NN USAGE NATIONAL VALUE N"123". 01 NATL-3 PIC NNN USAGE NATIONAL VALUE N"456". . . . INITIALIZE NATL-EDIT-1 REPLACING NATIONAL-EDITED DATA BY NATL-3 NATL-3 003400350036
1

NATL-EDIT-1 before 003100320033


2

NATL-EDIT-1 after 0030003400353

1. Hexadecimal representation of the national characters 456 2. Hexadecimal representation of the national characters 123 3. Hexadecimal representation of the national characters 045

Initializing a numeric (zoned decimal) data item:


01 NUMERIC-1 PIC 9(8) VALUE 98765432. 01 NUM-INT-CMPT-3 PIC 9(7) COMP VALUE 1234567. . . . INITIALIZE NUMERIC-1 REPLACING NUMERIC DATA BY NUM-INT-CMPT-3 NUM-INT-CMPT-3 1234567 NUMERIC-1 before 98765432 NUMERIC-1 after 01234567

Chapter 2. Using data

31

Initializing a numeric (national decimal) data item:


01 NAT-DEC-1 PIC 9(3) USAGE NATIONAL VALUE 987. 01 NUM-INT-BIN-3 PIC 9(2) BINARY VALUE 12. . . . INITIALIZE NAT-DEC-1 REPLACING NUMERIC DATA BY NUM-INT-BIN-3 NUM-INT-BIN-3 12 NAT-DEC-1 before 003900380037
1

NAT-DEC-1 after 0030003100322

1. Hexadecimal representation of the national characters 987 2. Hexadecimal representation of the national characters 012

Initializing a numeric-edited (USAGE DISPLAY) data item:


01 NUM-EDIT-DISP-1 PIC $ZZ9V VALUE "$127". 01 NUM-DISP-3 PIC 999V VALUE 12. . . . INITIALIZE NUM-EDIT-DISP-1 REPLACING NUMERIC DATA BY NUM-DISP-3 NUM-DISP-3 012 NUM-EDIT-DISP-1 before $127 NUM-EDIT-DISP-1 after $ 12

Initializing a numeric-edited (USAGE NATIONAL) data item:


01 NUM-EDIT-NATL-1 PIC $ZZ9V NATIONAL VALUE N"$127". 01 NUM-NATL-3 PIC 999V NATIONAL VALUE 12. . . . INITIALIZE NUM-EDIT-NATL-1 REPLACING NUMERIC DATA BY NUM-NATL-3 NUM-NATL-3 003000310032
1

NUM-EDIT-NATL-1 before 0024003100320037


2

NUM-EDIT-NATL-1 after 00240020003100323

1. Hexadecimal representation of the national characters 012 2. Hexadecimal representation of the national characters $127 3. Hexadecimal representation of the national characters $ 12

RELATED TASKS

Initializing a structure (INITIALIZE) Initializing a table (INITIALIZE) on page 76 Defining numeric data on page 45
RELATED REFERENCES

NSYMBOL on page 331

Initializing a structure (INITIALIZE)


You can reset the values of all subordinate data items in a group item by applying the INITIALIZE statement to that group item. However, it is inefficient to initialize an entire group unless you really need all the items in the group to be initialized. The following example shows how you can reset fields to spaces and zeros in transaction records that a program produces. The values of the fields are not

32

Enterprise COBOL for z/OS V4.2 Programming Guide

identical in each record that is produced. (The transaction record is defined as an alphanumeric group item, TRANSACTION-OUT.)
01 TRANSACTION-OUT. 05 TRANSACTION-CODE PIC X. 05 PART-NUMBER PIC 9(6). 05 TRANSACTION-QUANTITY PIC 9(5). 05 PRICE-FIELDS. 10 UNIT-PRICE PIC 9(5)V9(2). 10 DISCOUNT PIC V9(2). 10 SALES-PRICE PIC 9(5)V9(2). . . . INITIALIZE TRANSACTION-OUT Record 1 2 3 4 5 TRANSACTION-OUT before R001383000240000000000000000 R001390000480000000000000000 S001410000120000000000000000 C001383000000000425000000000 C002010000000000000100000000 TRANSACTION-OUT after b0000000000000000000000000001 b0000000000000000000000000001 b0000000000000000000000000001 b0000000000000000000000000001 b0000000000000000000000000001

1. The symbol b represents a blank space.

You can likewise reset the values of all the subordinate data items in a national group item by applying the INITIALIZE statement to that group item. The following structure is similar to the preceding structure, but instead uses Unicode UTF-16 data:
01 TRANSACTION-OUT GROUP-USAGE 05 TRANSACTION-CODE 05 PART-NUMBER 05 TRANSACTION-QUANTITY 05 PRICE-FIELDS. 10 UNIT-PRICE 10 DISCOUNT 10 SALES-PRICE . . . INITIALIZE TRANSACTION-OUT NATIONAL. PIC N. PIC 9(6). PIC 9(5). PIC 9(5)V9(2). PIC V9(2). PIC 9(5)V9(2).

Regardless of the previous contents of the transaction record, after the INITIALIZE statement above is executed: v TRANSACTION-CODE contains NX"0020" (a national space). v Each of the remaining 27 national character positions of TRANSACTION-OUT contains NX"0030" (a national-decimal zero). When you use an INITIALIZE statement to initialize an alphanumeric or national group data item, the data item is processed as a group item, that is, with group semantics. The elementary data items within the group are recognized and processed, as shown in the examples above. If you do not code the REPLACING phrase of the INITIALIZE statement: v SPACE is the implied sending item for alphabetic, alphanumeric, alphanumeric-edited, DBCS, category national, and national-edited receiving items. v ZERO is the implied sending item for numeric and numeric-edited receiving items.
RELATED CONCEPTS

National groups on page 129


Chapter 2. Using data

33

RELATED TASKS

Initializing a table (INITIALIZE) on page 76 Using national groups on page 130


RELATED REFERENCES

INITIALIZE statement (Enterprise COBOL Language Reference)

Assigning values to elementary data items (MOVE)


Use a MOVE statement to assign a value to an elementary data item. The following statement assigns the contents of an elementary data item, Customer-Name, to the elementary data item Orig-Customer-Name:
Move Customer-Name to Orig-Customer-Name

If Customer-Name is longer than Orig-Customer-Name, truncation occurs on the right. If Customer-Name is shorter, the extra character positions on the right in Orig-Customer-Name are filled with spaces. For data items that contain numbers, moves can be more complicated than with character data items because there are several ways in which numbers can be represented. In general, the algebraic values of numbers are moved if possible, as opposed to the digit-by-digit moves that are performed with character data. For example, after the MOVE statement below, Item-x contains the value 3.0, represented as 0030:
01 Item-x Pic 999v9. . . . Move 3.06 to Item-x

You can move an alphabetic, alphanumeric, alphanumeric-edited, DBCS, integer, or numeric-edited data item to a category national or national-edited data item; the sending item is converted. You can move a national data item to a category national or national-edited data item. If the content of a category national data item has a numeric value, you can move that item to a numeric, numeric-edited, external floating-point, or internal floating-point data item. You can move a national-edited data item only to a category national data item or another national-edited data item. Padding or truncation might occur. For complete details about elementary moves, see the related reference below about the MOVE statement. The following example shows an alphanumeric data item in the Greek language that is moved to a national data item:
CBL CODEPAGE(00875) . . . 01 Data-in-Unicode Pic N(100) usage national. 01 Data-in-Greek Pic X(100). . . . Read Greek-file into Data-in-Greek Move Data-in-Greek to Data-in-Unicode
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125

34

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED TASKS

Assigning values to group data items (MOVE) Converting to or from national (Unicode) representation on page 134
RELATED REFERENCES

CODEPAGE on page 310 Classes and categories of data (Enterprise COBOL Language Reference) MOVE statement (Enterprise COBOL Language Reference)

Assigning values to group data items (MOVE)


Use the MOVE statement to assign values to group data items. You can move a national group item (a data item that is described with the GROUP-USAGE NATIONAL clause) to another national group item. The compiler processes the move as though each national group item were an elementary item of category national, that is, as if each item were described as PIC N(m), where m is the length of that item in national character positions. You can move an alphanumeric group item to an alphanumeric group item or to a national group item. You can also move a national group item to an alphanumeric group item. The compiler performs such moves as group moves, that is, without consideration of the individual elementary items in the sending or receiving group, and without conversion of the sending data item. Be sure that the subordinate data descriptions in the sending and receiving group items are compatible. The moves occur even if a destructive overlap could occur at run time. You can code the CORRESPONDING phrase in a MOVE statement to move subordinate elementary items from one group item to the identically named corresponding subordinate elementary items in another group item:
01 Group-X. 02 T-Code Pic X Value "A". 02 Month Pic 99 Value 04. 02 State Pic XX Value "CA". 02 Filler PIC X. 01 Group-N Group-Usage National. 02 State Pic NN. 02 Month Pic 99. 02 Filler Pic N. 02 Total Pic 999. . . . MOVE CORR Group-X TO Group-N

In the example above, State and Month within Group-N receive the values in national representation of State and Month, respectively, from Group-X. The other data items in Group-N are unchanged. (Filler items in a receiving group item are unchanged by a MOVE CORRESPONDING statement.) In a MOVE CORRESPONDING statement, sending and receiving group items are treated as group items, not as elementary data items; group semantics apply. That is, the elementary data items within each group are recognized, and the results are the same as if each pair of corresponding data items were referenced in a separate MOVE statement. Data conversions are performed according to the rules for the MOVE statement as specified in the related reference below. For details about which types of elementary data items correspond, see the related reference about the CORRESPONDING phrase.

Chapter 2. Using data

35

RELATED CONCEPTS

Unicode and the encoding of language characters on page 125 National groups on page 129
RELATED TASKS

Assigning values to elementary data items (MOVE) on page 34 Using national groups on page 130 Converting to or from national (Unicode) representation on page 134
RELATED REFERENCES

Classes and categories of group items (Enterprise COBOL Language Reference) MOVE statement (Enterprise COBOL Language Reference) CORRESPONDING phrase (Enterprise COBOL Language Reference)

Assigning arithmetic results (MOVE or COMPUTE)


When assigning a number to a data item, consider using the COMPUTE statement instead of the MOVE statement.
Move w to z Compute z = w

In the example above, the two statements in most cases have the same effect. The MOVE statement however carries out the assignment with truncation. You can use the DIAGTRUNC compiler option to request that the compiler issue a warning for MOVE statements that might truncate numeric receivers. When significant left-order digits would be lost in execution, the COMPUTE statement can detect the condition and allow you to handle it. If you use the ON SIZE ERROR phrase of the COMPUTE statement, the compiler generates code to detect a size-overflow condition. If the condition occurs, the code in the ON SIZE ERROR phrase is performed, and the content of z remains unchanged. If you do not specify the ON SIZE ERROR phrase, the assignment is carried out with truncation. There is no ON SIZE ERROR support for the MOVE statement. You can also use the COMPUTE statement to assign the result of an arithmetic expression or intrinsic function to a data item. For example:
Compute z = y + (x ** 3) Compute x = Function Max(x y z)

You can assign the results of date, time, mathematical, and other calculations to data items by using Language Environment callable services. Language Environment services are available through a standard COBOL CALL statement, and the values they return are passed in the parameters of the CALL statement. For example, you can call the Language Environment service CEESIABS to find the absolute value of a data item by coding the following statement:
Call 'CEESIABS' Using Arg, Feedback-code, Result.

As a result of this call, data item Result is assigned the absolute value of the value in data item Arg; data item Feedback-code contains the return code that indicates whether the service completed successfully. You have to define all the data items in the DATA DIVISION using the correct descriptions according to the requirements of the particular callable service. For the example above, the data items could be defined as follows:
77 Arg Pic s9(9) Binary. 77 Feedback-code Pic x(12) Display. 77 Result Pic s9(9) Binary.

36

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED REFERENCES

DIAGTRUNC on page 318 Intrinsic functions (Enterprise COBOL Language Reference) Language Environment Programming Reference (Callable services)

Assigning input from a screen or file (ACCEPT)


One way to assign a value to a data item is to read the value from a screen or a file. To enter data from the screen, first associate the monitor with a mnemonic-name in the SPECIAL-NAMES paragraph. Then use ACCEPT to assign the line of input entered at the screen to a data item. For example:
Environment Division. Configuration Section. Special-Names. Console is Names-Input. . . . Accept Customer-Name From Names-Input

To read from a file instead of the screen, make the following change: v Change Console to device, where device is any valid system device (for example, SYSIN). For example:
SYSIN is Names-Input

device can be a ddname that references a hierarchical file system (HFS) path. If this ddname is not defined and your program is running in the z/OS UNIX environment, stdin is the input source. If this ddname is not defined and your program is not running in the z/OS UNIX environment, the ACCEPT statement fails. When you use the ACCEPT statement, you can assign a value to an alphanumeric or national group item, or to an elementary data item that has USAGE DISPLAY, USAGE DISPLAY-1, or USAGE NATIONAL. When you assign a value to a USAGE NATIONAL data item, input data from the console is converted from the EBCDIC code page specified in the CODEPAGE compiler option to national (Unicode UTF-16) representation. This is the only case where conversion of national data is done when you use the ACCEPT statement. Conversion is done in this case because the input is known to be coming from a screen. To have conversion done when the input data is from any other device, use the NATIONAL-OF intrinsic function.
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125


RELATED TASKS

Converting alphanumeric or DBCS to national (NATIONAL-OF) on page 135


RELATED REFERENCES

CODEPAGE on page 310 ACCEPT statement (Enterprise COBOL Language Reference) SPECIAL-NAMES paragraph (Enterprise COBOL Language Reference)

Chapter 2. Using data

37

Displaying values on a screen or in a file (DISPLAY)


You can display the value of a data item on a screen or write it to a file by using the DISPLAY statement.
Display "No entry for surname '" Customer-Name "' found in the file.".

In the example above, if the content of data item Customer-Name is JOHNSON, then the statement displays the following message on the system logical output device:
No entry for surname 'JOHNSON' found in the file.

To write data to a destination other than the system logical output device, use the UPON phrase with a destination other than SYSOUT. For example, the following statement writes to the file specified in the SYSPUNCH DD statement:
Display "Hello" upon syspunch.

You can specify a file in the HFS by using the SYSPUNCH DD statement. For example, the following definition causes DISPLAY output to be written to the file /u/userid/cobol/demo.lst:
//SYSPUNCH DD PATH='/u/userid/cobol/demo.lst', // PATHOPTS=(OWRONLY,OCREAT,OTRUNC),PATHMODE=SIRWXU, // FILEDATA=TEXT

The following statement writes to the job log or console and to the TSO screen if you are running under TSO:
Display "Hello" upon console.

When you display the value of a USAGE NATIONAL data item to the console, it is converted from Unicode (UTF-16) representation to EBCDIC based on the value of the CODEPAGE option. This is the only case where conversion of national data is done when you use the DISPLAY statement. Conversion is done in this case because the output is known to be directed to a screen. To have a national data item be converted when you direct output to a different device, use the DISPLAY-OF intrinsic function, such as in the following example:
01 Data-in-Unicode pic N(10) usage national. . . . Display function Display-of(Data-in-Unicode, 00037)
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125


RELATED TASKS

Displaying data on the system logical output device on page 39 Using WITH NO ADVANCING on page 39 Converting national to alphanumeric (DISPLAY-OF) on page 136 Coding COBOL programs to run under CICS on page 407
RELATED REFERENCES

CODEPAGE on page 310 DISPLAY statement (Enterprise COBOL Language Reference)

38

Enterprise COBOL for z/OS V4.2 Programming Guide

Displaying data on the system logical output device


To write data to the system logical output device, either omit the UPON clause or use the UPON clause with destination SYSOUT.
Display "Hello" upon sysout.

The output is directed to the ddname that you specify in the OUTDD compiler option. You can specify a file in the hierarchical file system with this ddname. If the OUTDD ddname is not allocated and you are not running in the z/OS UNIX environment, a default DD of SYSOUT=* is allocated. If the OUTDD ddname is not allocated and you are running in the z/OS UNIX environment, the _IGZ_SYSOUT environment variable is used as follows: Undefined or set to stdout Output is routed to stdout (file descriptor 1). Set to stderr Output is routed to stderr (file descriptor 2). Otherwise (set to something other than stdout or stderr) The DISPLAY statement fails; a severity-3 Language Environment condition is raised. When DISPLAY output is routed to stdout or stderr, the output is not subdivided into records. The output is written as a single stream of characters without line breaks. If OUTDD and the Language Environment runtime option MSGFILE specify the same ddname, both DISPLAY output and Language Environment runtime diagnostics are routed to the Language Environment message file.
RELATED TASKS

Setting and accessing environment variables on page 438


RELATED REFERENCES

OUTDD on page 337 DISPLAY statement (Enterprise COBOL Language Reference)

Using WITH NO ADVANCING


If you specify the WITH NO ADVANCING phrase, and output is going to a ddname, the printer control character + (plus) is placed into the first output position from the next DISPLAY statement. + is the ANSI-defined printer control character that suppresses line spacing before a record is printed. If you specify the WITH NO ADVANCING phrase and the output is going to stdout or stderr, a newline character is not appended to the end of the stream. A subsequent DISPLAY statement might add additional characters to the end of the stream. If you do not specify WITH NO ADVANCING, and the output is going to a ddname, the printer control character (space) is placed into the first output position from the next DISPLAY statement, indicating single-spaced output.

Chapter 2. Using data

39

DISPLAY DISPLAY DISPLAY DISPLAY DISPLAY

"ABC" "CDEF" WITH NO ADVANCING "GHIJK" WITH NO ADVANCING "LMNOPQ" "RSTUVWX"

If you code the statements above, the result sent to the output device is:
ABC CDEF +GHIJK +LMNOPQ RSTUVMX

The output that is printed depends on how the output device interprets printer control characters. If you do not specify the WITH NO ADVANCING phrase and the output is going to stdout or stderr, a newline character is appended to the end of the stream.
RELATED REFERENCES

DISPLAY statement (Enterprise COBOL Language Reference)

Using intrinsic functions (built-in functions)


Some high-level programming languages have built-in functions that you can reference in your program as if they were variables that have defined attributes and a predetermined value. In COBOL, these functions are called intrinsic functions. They provide capabilities for manipulating strings and numbers. Because the value of an intrinsic function is derived automatically at the time of reference, you do not need to define functions in the DATA DIVISION. Define only the nonliteral data items that you use as arguments. Figurative constants are not allowed as arguments. A function-identifier is the combination of the COBOL reserved word FUNCTION followed by a function name (such as Max), followed by any arguments to be used in the evaluation of the function (such as x, y, z). For example, the groups of highlighted words below are function-identifiers:
Unstring Function Upper-case(Name) Delimited By Space Into Fname Lname Compute A = 1 + Function Log10(x) Compute M = Function Max(x y z)

A function-identifier represents both the invocation of the function and the data value returned by the function. Because it actually represents a data item, you can use a function-identifier in most places in the PROCEDURE DIVISION where a data item that has the attributes of the returned value can be used. The COBOL word function is a reserved word, but the function-names are not reserved. You can use them in other contexts, such as for the name of a data item. For example, you could use Sqrt to invoke an intrinsic function and to name a data item in your program:
Working-Storage Section. 01 x Pic 99 value 2. 01 y Pic 99 value 4. 01 z Pic 99 value 0. 01 Sqrt Pic 99 value 0.

40

Enterprise COBOL for z/OS V4.2 Programming Guide

. . . Compute Sqrt = 16 ** .5 Compute z = x + Function Sqrt(y) . . .

A function-identifier represents a value that is of one of these types: alphanumeric, national, numeric, or integer. You can include a substring specification (reference modifier) in a function-identifier for alphanumeric or national functions. Numeric intrinsic functions are further classified according to the type of numbers they return. The functions MAX, MIN, DATEVAL, and UNDATE can return either type of value depending on the type of arguments you supply. The functions DATEVAL, UNDATE, and YEARWINDOW are provided with the millennium language extensions to assist with manipulating and converting windowed date fields. Functions can reference other functions as arguments provided that the results of the nested functions meet the requirements for the arguments of the outer function. For example, Function Sqrt(5) returns a numeric value. Thus, the three arguments to the MAX function below are all numeric, which is an allowable argument type for this function:
Compute x = Function Max((Function Sqrt(5)) 2.5 3.5)
RELATED TASKS

Processing table items using intrinsic functions on page 86 Converting data items (intrinsic functions) on page 112 Evaluating data items (intrinsic functions) on page 115

Using tables (arrays) and pointers


In COBOL, arrays are called tables. A table is a set of logically consecutive data items that you define in the DATA DIVISION by using the OCCURS clause. Pointers are data items that contain virtual storage addresses. You define them either explicitly with the USAGE IS POINTER clause in the DATA DIVISION or implicitly as ADDRESS OF special registers. You can perform the following operations with pointer data items: v Pass them between programs by using the CALL . . . BY REFERENCE statement. v Move them to other pointers by using the SET statement. v Compare them to other pointers for equality by using a relation condition. v Initialize them to contain an invalid address by using VALUE IS NULL. Use pointer data items to: v Accomplish limited base addressing, particularly if you want to pass and receive addresses of a record area that is defined with OCCURS DEPENDING ON and is therefore variably located. v Handle a chained list.
RELATED TASKS

Defining a table (OCCURS) on page 69 Using procedure and function pointers on page 462
Chapter 2. Using data

41

Storage and its addressability


When you run COBOL programs, the programs and the data that they use reside in virtual storage. Storage that you use with COBOL can be either below the 16-MB line or above the 16-MB line but below the 2-GB bar. Two modes of addressing are available to address this storage: 24-bit and 31-bit. You can address storage below (but not above) the 16-MB line with 24-bit addressing. You can address storage either above or below the 16-MB line with 31-bit addressing. Unrestricted storage is addressable by 31-bit addressing and therefore encompasses all the storage available to your program, both above and below the 16-MB line. Enterprise COBOL does not directly exploit the 64-bit virtual addressing capability of z/OS; however, COBOL applications running in 31-bit or 24-bit addressing mode are fully supported on 64-bit z/OS systems. Addressing mode (AMODE) is the attribute that tells which hardware addressing mode is supported by your program: 24-bit addressing, 31-bit addressing, or either 24-bit or 31-bit addressing. This attribute is AMODE 24, AMODE 31, or AMODE ANY, respectively. The object program, the load module, and the executing program each has an AMODE attribute. All Enterprise COBOL object programs are AMODE ANY. Residency mode (RMODE) is the attribute of a program load module that identifies where in virtual storage the program will reside: below the 16-MB line, or either below or above. This attribute is RMODE 24 or RMODE ANY. Enterprise COBOL uses Language Environment services to control the storage used at run time. Thus COBOL compiler options and Language Environment runtime options influence the AMODE and RMODE attributes of your program and data, alone and in combination: DATA RMODE Compiler option that influences the location of storage for WORKING-STORAGE data, I-O buffers, and parameter lists for programs compiled with RENT. Compiler option that influences the residency mode and also influences the location of storage for WORKING-STORAGE data, I-O buffers, and parameter lists for programs compiled with NORENT. Compiler option to generate a reentrant program. Runtime option that controls storage for the runtime heap. For example, COBOL WORKING-STORAGE is allocated from heap storage. Runtime option that controls storage for the runtime stack. For example, COBOL LOCAL-STORAGE is allocated from stack storage. Runtime option that specifies whether an application can run entirely in AMODE 31.

RENT HEAP STACK ALL31

Settings for RMODE


The RMODE and RENT options determine the RMODE attribute of your program.
Table 4. Effect of RMODE and RENT compiler options on the RMODE attribute RMODE compiler option RMODE(AUTO) RMODE(AUTO) RENT compiler option NORENT RENT RMODE attribute RMODE 24 RMODE ANY

42

Enterprise COBOL for z/OS V4.2 Programming Guide

Table 4. Effect of RMODE and RENT compiler options on the RMODE attribute (continued) RMODE compiler option RMODE(24) RMODE(ANY) RENT compiler option RENT or NORENT RENT or NORENT RMODE attribute RMODE 24 RMODE ANY

Link-edit considerations: When the object code that COBOL generates has an attribute of RMODE 24, you must link-edit it with RMODE 24. When the object code that COBOL generates has an attribute of RMODE ANY, you can link-edit it with RMODE ANY or RMODE 24.

Storage restrictions for passing data


Do not pass parameters that are allocated in storage above the 16-MB line to AMODE 24 subprograms. Force the WORKING-STORAGE data and parameter lists below the line for programs that run in 31-bit addressing mode and pass data to programs that run in AMODE 24: v Compile reentrant programs (RENT) with DATA(24). v Compile nonreentrant programs (NORENT) with RMODE(24) or RMODE(AUTO). v Nonreentrant programs (NORENT) compiled with RMODE(ANY) must be link-edited with RMODE 24. The data areas for NORENT programs are above the 16-MB line or below the 16-MB line depending on where the program is loaded, even if the program was compiled with DATA(24). The DATA option does not affect programs compiled with NORENT.

Location of data areas


For reentrant programs, the DATA compiler option and the HEAP runtime option control whether storage for data areas such as WORKING-STORAGE SECTION and FD record areas is obtained from below the 16-MB line or from unrestricted storage. Compile programs with RENT or RMODE(ANY) if they will be run with 31-bit addressing in virtual storage addresses above the 16-MB line. The DATA option does not affect programs compiled with NORENT. When you specify the runtime option HEAP(,,BELOW), the DATA compiler option has no effect; the storage for WORKING-STORAGE SECTION data areas is allocated from below the 16-MB line. However, with HEAP(,,ANYWHERE) as the runtime option, storage for data areas is allocated from below the 16-MB line if you compiled the program with the DATA(24) compiler option, or from unrestricted storage if you compiled with the DATA(31) compiler option.

Storage for LOCAL-STORAGE data


The location of LOCAL-STORAGE data items is controlled by the STACK runtime option and the AMODE of the program. LOCAL-STORAGE data items are acquired in unrestricted storage when the STACK(,,ANYWHERE) runtime option is in effect and the program is running in AMODE 31. Otherwise LOCAL-STORAGE is acquired below the 16-MB line. The DATA compiler option does not influence the location of LOCAL-STORAGE data.

Chapter 2. Using data

43

Storage for external data


In addition to affecting how storage is obtained for dynamic data areas (WORKING-STORAGE, FD record areas, and parameter lists), the DATA compiler option can also influence where storage for EXTERNAL data is obtained. Storage required for EXTERNAL data is obtained from unrestricted storage if the following conditions are met: v The program is compiled with the DATA(31) and RENT compiler options or the RMODE(ANY) and NORENT compiler options. v The HEAP(,,ANYWHERE) runtime option is in effect. v The ALL31(ON) runtime option is in effect. In all other cases, the storage for EXTERNAL data is obtained from below the 16-MB line. If you specify the ALL31(ON) runtime option, all the programs in the run unit must be capable of running in 31-bit addressing mode.

Storage for QSAM input-output buffers


The DATA compiler option can also influence where input-output buffers for QSAM files are obtained. See the related references below for information about allocation of buffers for QSAM files and the DATA compiler option.
RELATED CONCEPTS

AMODE switching on page 453 Language Environment Programming Guide (AMODE considerations for heap storage)
RELATED TASKS

Chapter 24, Using subprograms, on page 447 Chapter 25, Sharing data, on page 465
RELATED REFERENCES

Allocation of buffers for QSAM files on page 173 DATA on page 314 RENT on page 341 RMODE on page 342 Performance-related compiler options on page 672 Language Environment Programming Reference (HEAP, STACK, ALL31) MVS Program Management: Users Guide and Reference

44

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 3. Working with numbers and arithmetic


In general, you can view COBOL numeric data as a series of decimal digit positions. However, numeric items can also have special properties such as an arithmetic sign or a currency sign. To define, display, and store numeric data so that you can perform arithmetic operations efficiently: v Use the PICTURE clause and the characters 9, +, -, P, S, and V to define numeric data. v Use the PICTURE clause and editing characters (such as Z, comma, and period) along with MOVE and DISPLAY statements to display numeric data. v Use the USAGE clause with various formats to control how numeric data is stored. v Use the numeric class test to validate that data values are appropriate. v Use ADD, SUBTRACT, MULTIPLY, DIVIDE, and COMPUTE statements to perform arithmetic. v Use the CURRENCY SIGN clause and appropriate PICTURE characters to designate the currency you want.
RELATED TASKS

Defining numeric data Displaying numeric data on page 47 Controlling how numeric data is stored on page 48 Checking for incompatible data (numeric class test) on page 56 Performing arithmetic on page 57 Using currency signs on page 67

Defining numeric data


Define numeric items by using the PICTURE clause with the character 9 in the data description to represent the decimal digits of the number. Do not use an X, which is for alphanumeric data items. For example, Count-y below is a numeric data item, an external decimal item that has USAGE DISPLAY (a zoned decimal item):
05 05 Count-y Pic 9(4) Value 25. Customer-name Pic X(20) Value "Johnson".

You can similarly define numeric data items to hold national characters (UTF-16). For example, Count-n below is an external decimal data item that has USAGE NATIONAL (a national decimal item):
05 Count-n Pic 9(4) Value 25 Usage National.

You can code up to 18 digits in the PICTURE clause when you compile using the default compiler option ARITH(COMPAT) (referred to as compatibility mode). When you compile using ARITH(EXTEND) (referred to as extended mode), you can code up to 31 digits in the PICTURE clause. Other characters of special significance that you can code are: P
Copyright IBM Corp. 1991, 2009

Indicates leading or trailing zeros

45

S V

Indicates a sign, positive or negative Implies a decimal point

The s in the following example means that the value is signed:


05 Price Pic s99v99.

The field can therefore hold a positive or a negative value. The v indicates the position of an implied decimal point, but does not contribute to the size of the item because it does not require a storage position. An s usually does not contribute to the size of a numeric item, because by default s does not require a storage position. However, if you plan to port your program or data to a different machine, you might want to code the sign for a zoned decimal data item as a separate position in storage. In the following case, the sign takes 1 byte:
05 Price Pic s99V99 Sign Is Leading, Separate.

This coding ensures that the convention your machine uses for storing a nonseparate sign will not cause unexpected results on a machine that uses a different convention. Separate signs are also preferable for zoned decimal data items that will be printed or displayed. Separate signs are required for national decimal data items that are signed. The sign takes 2 bytes of storage, as in the following example:
05 Price Pic s99V99 Usage National Sign Is Leading, Separate.

You cannot use the PICTURE clause with internal floating-point data (COMP-1 or COMP-2). However, you can use the VALUE clause to provide an initial value for an internal floating-point literal:
05 Compute-result Usage Comp-2 Value 06.23E-24.

For information about external floating-point data, see the examples referenced below and the related concept about formats for numeric data. Examples: numeric data and internal representation on page 52
RELATED CONCEPTS

Formats for numeric data on page 49 Appendix A, Intermediate results and arithmetic precision, on page 687
RELATED TASKS

Displaying numeric data on page 47 Controlling how numeric data is stored on page 48 Performing arithmetic on page 57 Defining national numeric data items on page 129
RELATED REFERENCES

Sign representation of zoned and packed-decimal data on page 55 Storage of character data on page 133 ARITH on page 306 NUMPROC on page 333 SIGN clause (Enterprise COBOL Language Reference)

46

Enterprise COBOL for z/OS V4.2 Programming Guide

Displaying numeric data


You can define numeric items with certain editing symbols (such as decimal points, commas, dollar signs, and debit or credit signs) to make the items easier to read and understand when you display or print them. For example, in the code below, Edited-price is a numeric-edited item that has USAGE DISPLAY. (You can specify the clause USAGE IS DISPLAY for numeric-edited items; however, it is implied. It means that the items are stored in character format.)
05 Price Pic 9(5)v99. 05 Edited-price Pic $zz,zz9.99. . . . Move Price To Edited-price Display Edited-price

If the contents of Price are 0150099 (representing the value 1,500.99), $ 1,500.99 is displayed when you run the code. The z in the PICTURE clause of Edited-price indicates the suppression of leading zeros. You can define numeric-edited data items to hold national (UTF-16) characters instead of alphanumeric characters. To do so, declare the numeric-edited items as USAGE NATIONAL. The effect of the editing symbols is the same for numeric-edited items that have USAGE NATIONAL as it is for numeric-edited items that have USAGE DISPLAY, except that the editing is done with national characters. For example, if Edited-price is declared as USAGE NATIONAL in the code above, the item is edited and displayed using national characters. To display numeric or numeric-edited data items that have USAGE NATIONAL in EBCDIC, direct them to CONSOLE. For example, if Edited-price in the code above has USAGE NATIONAL, $ 1,500.99 is displayed when you run the program if the last statement above is:
Display Edited-price Upon Console

You can cause an elementary numeric or numeric-edited item to be filled with spaces when a value of zero is stored into it by coding the BLANK WHEN ZERO clause for the item. For example, each of the DISPLAY statements below causes blanks to be displayed instead of zeros:
05 Price Pic 9(5)v99. 05 Edited-price-D Pic $99,999.99 Blank When Zero. 05 Edited-price-N Pic $99,999.99 Usage National Blank When Zero. . . . Move 0 to Price Move Price to Edited-price-D Move Price to Edited-price-N Display Edited-price-D Display Edited-price-N upon console

You cannot use numeric-edited items as sending operands in arithmetic expressions or in ADD, SUBTRACT, MULTIPLY, DIVIDE, or COMPUTE statements. (Numeric editing takes place when a numeric-edited item is the receiving field for one of these statements, or when a MOVE statement has a numeric-edited receiving field and a numeric-edited or numeric sending field.) You use numeric-edited items primarily for displaying or printing numeric data.

Chapter 3. Working with numbers and arithmetic

47

You can move numeric-edited items to numeric or numeric-edited items. In the following example, the value of the numeric-edited item (whether it has USAGE DISPLAY or USAGE NATIONAL) is moved to the numeric item:
Move Edited-price to Price Display Price

If these two statements immediately followed the statements in the first example above, then Price would be displayed as 0150099, representing the value 1,500.99. Price would also be displayed as 0150099 if Edited-price had USAGE NATIONAL. You can also move numeric-edited items to alphanumeric, alphanumeric-edited, floating-point, and national data items. For a complete list of the valid receiving items for numeric-edited data, see the related reference about the MOVE statement. Examples: numeric data and internal representation on page 52
RELATED TASKS

Displaying values on a screen or in a file (DISPLAY) on page 38 Controlling how numeric data is stored Defining numeric data on page 45 Performing arithmetic on page 57 Defining national numeric data items on page 129 Converting to or from national (Unicode) representation on page 134
RELATED REFERENCES

MOVE statement (Enterprise COBOL Language Reference) BLANK WHEN ZERO clause (Enterprise COBOL Language Reference)

Controlling how numeric data is stored


You can control how the computer stores numeric data items by coding the USAGE clause in your data description entries. You might want to control the format for any of several reasons such as these: v Arithmetic performed with computational data types is more efficient than with USAGE DISPLAY or USAGE NATIONAL data types. v Packed-decimal format requires less storage per digit than USAGE DISPLAY or USAGE NATIONAL data types. v Packed-decimal format converts to and from DISPLAY or NATIONAL format more efficiently than binary format does. v Floating-point format is well suited for arithmetic operands and results with widely varying scale, while maintaining the maximal number of significant digits. v You might need to preserve data formats when you move data from one machine to another. The numeric data you use in your program will have one of the following formats available with COBOL: v External decimal (USAGE DISPLAY or USAGE NATIONAL) v External floating point (USAGE DISPLAY or USAGE NATIONAL) v Internal decimal (USAGE PACKED-DECIMAL) v Binary (USAGE BINARY) v Native binary (USAGE COMP-5)

48

Enterprise COBOL for z/OS V4.2 Programming Guide

v Internal floating point (USAGE COMP-1 or USAGE COMP-2) COMP and COMP-4 are synonymous with BINARY, and COMP-3 is synonymous with PACKED-DECIMAL. The compiler converts displayable numbers to the internal representation of their numeric values before using them in arithmetic operations. Therefore it is often more efficient if you define data items as BINARY or PACKED-DECIMAL than as DISPLAY or NATIONAL. For example:
05 Initial-count Pic S9(4) Usage Binary Value 1000.

Regardless of which USAGE clause you use to control the internal representation of a value, you use the same PICTURE clause conventions and decimal value in the VALUE clause (except for internal floating-point data, for which you cannot use a PICTURE clause). Examples: numeric data and internal representation on page 52
RELATED CONCEPTS

Formats for numeric data Data format conversions on page 54 Appendix A, Intermediate results and arithmetic precision, on page 687
RELATED TASKS

Defining numeric data on page 45 Displaying numeric data on page 47 Performing arithmetic on page 57
RELATED REFERENCES

Conversions and precision on page 54 Sign representation of zoned and packed-decimal data on page 55

Formats for numeric data


Several formats are available for numeric data.

External decimal (DISPLAY and NATIONAL) items


When USAGE DISPLAY is in effect for a category numeric data item (either because you have coded it, or by default), each position (byte) of storage contains one decimal digit. The items are stored in displayable form. External decimal items that have USAGE DISPLAY are referred to as zoned decimal data items. When USAGE NATIONAL is in effect for a category numeric data item, 2 bytes of storage are required for each decimal digit. The items are stored in UTF-16 format. External decimal items that have USAGE NATIONAL are referred to as national decimal data items. National decimal data items, if signed, must have the SIGN SEPARATE clause in effect. All other rules for zoned decimal items apply to national decimal items. You can use national decimal items anywhere that other category numeric data items can be used. External decimal (both zoned decimal and national decimal) data items are primarily intended for receiving and sending numbers between your program and
Chapter 3. Working with numbers and arithmetic

49

files, terminals, or printers. You can also use external decimal items as operands and receivers in arithmetic processing. However, if your program performs a lot of intensive arithmetic, and efficiency is a high priority, COBOLs computational numeric types might be a better choice for the data items used in the arithmetic.

External floating-point (DISPLAY and NATIONAL) items


When USAGE DISPLAY is in effect for a floating-point data item (either because you have coded it, or by default), each PICTURE character position (except for v, an implied decimal point, if used) takes 1 byte of storage. The items are stored in displayable form. External floating-point items that have USAGE DISPLAY are referred to as display floating-point data items in this information when necessary to distinguish them from external floating-point items that have USAGE NATIONAL. In the following example, Compute-Result is implicitly defined as a display floating-point item:
05 Compute-Result Pic -9v9(9)E-99.

The minus signs (-) do not mean that the mantissa and exponent must necessarily be negative numbers. Instead, they mean that when the number is displayed, the sign appears as a blank for positive numbers or a minus sign for negative numbers. If you instead code a plus sign (+), the sign appears as a plus sign for positive numbers or a minus sign for negative numbers. When USAGE NATIONAL is in effect for a floating-point data item, each PICTURE character position (except for v, if used) takes 2 bytes of storage. The items are stored as national characters (UTF-16). External floating-point items that have USAGE NATIONAL are referred to as national floating-point data items. The existing rules for display floating-point items apply to national floating-point items. In the following example, Compute-Result-N is a national floating-point item:
05 Compute-Result-N Pic -9v9(9)E-99 Usage National.

If Compute-Result-N is displayed, the signs appear as described above for Compute-Result, but in national characters. To instead display Compute-Result-N in EBCDIC characters, direct it to the console:
Display Compute-Result-N Upon Console

You cannot use the VALUE clause for external floating-point items. As with external decimal numbers, external floating-point numbers have to be converted (by the compiler) to an internal representation of their numeric value before they can be used in arithmetic operations. If you compile with the default option ARITH (COMPAT), external floating-point numbers are converted to long (64-bit) floating-point format. If you compile with ARITH (EXTEND), they are instead converted to extended-precision (128-bit) floating-point format.

Binary (COMP) items


BINARY, COMP, and COMP-4 are synonyms. Binary-format numbers occupy 2, 4, or 8 bytes of storage. If the PICTURE clause specifies that an item is signed, the leftmost bit is used as the operational sign.

50

Enterprise COBOL for z/OS V4.2 Programming Guide

A binary number with a PICTURE description of four or fewer decimal digits occupies 2 bytes; five to nine decimal digits, 4 bytes; and 10 to 18 decimal digits, 8 bytes. Binary items with nine or more digits require more handling by the compiler. Testing them for the SIZE ERROR condition and rounding is more cumbersome than with other types. You can use binary items, for example, for indexes, subscripts, switches, and arithmetic operands or results. Use the TRUNC(STD|OPT|BIN) compiler option to indicate how binary data (BINARY, COMP, or COMP-4) is to be truncated.

Native binary (COMP-5) items


Data items that you declare as USAGE COMP-5 are represented in storage as binary data. However, unlike USAGE COMP items, they can contain values of magnitude up to the capacity of the native binary representation (2, 4, or 8 bytes) rather than being limited to the value implied by the number of 9s in the PICTURE clause. When you move or store numeric data into a COMP-5 item, truncation occurs at the binary field size rather than at the COBOL PICTURE size limit. When you reference a COMP-5 item, the full binary field size is used in the operation. COMP-5 is thus particularly useful for binary data items that originate in non-COBOL programs where the data might not conform to a COBOL PICTURE clause. The table below shows the ranges of possible values for COMP-5 data items.
Table 5. Ranges in value of COMP-5 data items PICTURE S9(1) through S9(4) S9(5) through S9(9) S9(10) through S9(18) 9(1) through 9(4) 9(5) through 9(9) 9(10) through 9(18) Storage representation Binary halfword (2 bytes) Binary fullword (4 bytes) Binary doubleword (8 bytes) Binary halfword (2 bytes) Binary fullword (4 bytes) Binary doubleword (8 bytes) Numeric values -32768 through +32767 -2,147,483,648 through +2,147,483,647 -9,223,372,036,854,775,808 through +9,223,372,036,854,775,807 0 through 65535 0 through 4,294,967,295 0 through 18,446,744,073,709,551,615

You can specify scaling (that is, decimal positions or implied integer positions) in the PICTURE clause of COMP-5 items. If you do so, you must appropriately scale the maximal capacities listed above. For example, a data item you describe as PICTURE S99V99 COMP-5 is represented in storage as a binary halfword, and supports a range of values from -327.68 through +327.67. Large literals in VALUE clauses: Literals specified in VALUE clauses for COMP-5 items can, with a few exceptions, contain values of magnitude up to the capacity of the native binary representation. See Enterprise COBOL Language Reference for the exceptions. Regardless of the setting of the TRUNC compiler option, COMP-5 data items behave like binary data does in programs compiled with TRUNC(BIN).
Chapter 3. Working with numbers and arithmetic

51

Packed-decimal (COMP-3) items


PACKED-DECIMAL and COMP-3 are synonyms. Packed-decimal items occupy 1 byte of storage for every two decimal digits you code in the PICTURE description, except that the rightmost byte contains only one digit and the sign. This format is most efficient when you code an odd number of digits in the PICTURE description, so that the leftmost byte is fully used. Packed-decimal items are handled as fixed-point numbers for arithmetic purposes.

Internal floating-point (COMP-1 and COMP-2) items


COMP-1 refers to short floating-point format and COMP-2 refers to long floating-point format, which occupy 4 and 8 bytes of storage, respectively. The leftmost bit contains the sign and the next 7 bits contain the exponent; the remaining 3 or 7 bytes contain the mantissa. COMP-1 and COMP-2 data items are stored in zSeries hexadecimal format.
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125 Appendix A, Intermediate results and arithmetic precision, on page 687
RELATED TASKS

Defining numeric data on page 45 Defining national numeric data items on page 129
RELATED REFERENCES

Storage of character data on page 133 TRUNC on page 353 Classes and categories of data (Enterprise COBOL Language Reference) SIGN clause (Enterprise COBOL Language Reference) VALUE clause (Enterprise COBOL Language Reference)

Examples: numeric data and internal representation


The following table shows the internal representation of numeric items.

52

Enterprise COBOL for z/OS V4.2 Programming Guide

Table 6. Internal representation of numeric items Numeric type PICTURE and USAGE and optional SIGN clause Value + 1234 - 1234 1234 PIC 9999 DISPLAY PIC 9999 NATIONAL PIC S9999 DISPLAY SIGN LEADING PIC S9999 DISPLAY SIGN LEADING SEPARATE PIC S9999 DISPLAY SIGN TRAILING SEPARATE PIC S9999 NATIONAL SIGN LEADING SEPARATE PIC S9999 NATIONAL SIGN TRAILING SEPARATE Binary PIC S9999 BINARY PIC S9999 COMP PIC S9999 COMP-4 PIC S9999 COMP-5 1234 1234 + 1234 - 1234 + 1234 - 1234 + 1234 - 1234 + 1234 - 1234 + 1234 - 1234 + 1234 - 1234 + 123451 - 12345 PIC 9999 PIC 9999 PIC 9999 PIC 9999 BINARY COMP COMP-4 COMP-5 1234
1

Internal representation F1 F2 F3 C4 F1 F2 F3 D4 F1 F2 F3 C4 F1 F2 F3 F4 00 31 00 32 00 33 00 34 C1 F2 F3 F4 D1 F2 F3 F4 4E F1 F2 F3 F4 60 F1 F2 F3 F4 F1 F2 F3 F4 4E F1 F2 F3 F4 60 00 2B 00 31 00 32 00 33 00 34 00 2D 00 31 00 32 00 33 00 34 00 31 00 32 00 33 00 34 00 2B 00 31 00 32 00 33 00 34 00 2D 04 D2 FB 2E 30 39 CF C7 04 D2

External decimal PIC S9999 DISPLAY

600001 + 1234 - 1234 1234 + 1234 - 1234

EA 60 01 23 4C 01 23 4D 01 23 4F 43 4D 20 00 C3 4D 20 00 43 4D 20 00 00 00 00 00 C3 4D 20 00 00 00 00 00 4E F1 F2 4B F3 F4 C5 4E F0 F2 60 F1 F2 4B F3 F4 C5 4E F0 F2 00 2B 00 31 00 32 00 2E 00 33 00 34 00 45 00 2B 00 30 00 32 00 2D 00 31 00 32 00 2E 00 33 00 34 00 45 00 2B 00 30 00 32

Internal decimal PIC S9999 PACKED-DECIMAL PIC S9999 COMP-3 PIC 9999 PIC 9999 Internal floating point COMP-1 PACKED-DECIMAL COMP-3

COMP-2

+ 1234 - 1234

External floating PIC +9(2).9(2)E+99 DISPLAY point PIC +9(2).9(2)E+99 NATIONAL

+ 12.34E+02 - 12.34E+02 + 12.34E+02 - 12.34E+02

1. The example demonstrates that COMP-5 data items can contain values of magnitude up to the capacity of the native binary representation (2, 4, or 8 bytes), rather than being limited to the value implied by the number of 9s in the PICTURE clause.

Chapter 3. Working with numbers and arithmetic

53

Data format conversions


When the code in your program involves the interaction of items that have different data formats, the compiler converts those items either temporarily, for comparisons and arithmetic operations, or permanently, for assignment to the receiver in a MOVE or COMPUTE statement. A conversion is actually a move of a value from one data item to another. The compiler performs any conversions that are required during the execution of arithmetic or comparisons by using the same rules that are used for MOVE and COMPUTE statements. When possible, the compiler performs a move to preserve numeric value instead of a direct digit-for-digit move. Conversion generally requires additional storage and processing time because data is moved to an internal work area and converted before the operation is performed. The results might also have to be moved back into a work area and converted again. Conversions between fixed-point data formats (external decimal, packed decimal, or binary) are without loss of precision provided that the target field can contain all the digits of the source operand. A loss of precision is possible in conversions between fixed-point data formats and floating-point data formats (short floating point, long floating point, or external floating point). These conversions happen during arithmetic evaluations that have a mixture of both fixed-point and floating-point operands.
RELATED REFERENCES

Conversions and precision Sign representation of zoned and packed-decimal data on page 55

Conversions and precision


In some numeric conversions, a loss of precision is possible; other conversions preserve precision or result in rounding. Because both fixed-point and external floating-point items have decimal characteristics, references to fixed-point items in the following examples include external floating-point items unless stated otherwise. When the compiler converts from fixed-point to internal floating-point format, fixed-point numbers in base 10 are converted to the numbering system used internally. When the compiler converts short form to long form for comparisons, zeros are used for padding the shorter number.

Conversions that lose precision


When a USAGE COMP-1 data item is moved to a fixed-point data item that has more than nine digits, the fixed-point data item will receive only nine significant digits, and the remaining digits will be zero.

54

Enterprise COBOL for z/OS V4.2 Programming Guide

When a USAGE COMP-2 data item is moved to a fixed-point data item that has more than 18 digits, the fixed-point data item will receive only 18 significant digits, and the remaining digits will be zero.

Conversions that preserve precision


If a fixed-point data item that has six or fewer digits is moved to a USAGE COMP-1 data item and then returned to the fixed-point data item, the original value is recovered. If a USAGE COMP-1 data item is moved to a fixed-point data item of nine or more digits and then returned to the USAGE COMP-1 data item, the original value is recovered. If a fixed-point data item that has 15 or fewer digits is moved to a USAGE COMP-2 data item and then returned to the fixed-point data item, the original value is recovered. If a USAGE COMP-2 data item is moved to a fixed-point (not external floating-point) data item of 18 or more digits and then returned to the USAGE COMP-2 data item, the original value is recovered.

Conversions that result in rounding


If a USAGE COMP-1 data item, a USAGE COMP-2 data item, an external floating-point data item, or a floating-point literal is moved to a fixed-point data item, rounding occurs in the low-order position of the target data item. If a USAGE COMP-2 data item is moved to a USAGE COMP-1 data item, rounding occurs in the low-order position of the target data item. If a fixed-point data item is moved to an external floating-point data item and the PICTURE of the fixed-point data item contains more digit positions than the PICTURE of the external floating-point data item, rounding occurs in the low-order position of the target data item.
RELATED CONCEPTS

Appendix A, Intermediate results and arithmetic precision, on page 687

Sign representation of zoned and packed-decimal data


Sign representation affects the processing and interaction of zoned decimal and internal decimal data. Given X'sd', where s is the sign representation and d represents the digit, the valid sign representations for zoned decimal (USAGE DISPLAY) data without the SIGN IS SEPARATE clause are: Positive: C, A, E, and F Negative: D and B The COBOL NUMPROC compiler option affects sign processing for zoned decimal and internal decimal data. NUMPROC has no effect on binary data, national decimal data, or floating-point data.
Chapter 3. Working with numbers and arithmetic

55

NUMPROC(PFD) Given X'sd', where s is the sign representation and d represents the digit, when you use NUMPROC(PFD), the compiler assumes that the sign in your data is one of three preferred signs: Signed positive or 0: X'C' Signed negative: X'D' Unsigned or alphanumeric: X'F' Based on this assumption, the compiler uses whatever sign it is given to process data. The preferred sign is generated only where necessary (for example, when unsigned data is moved to signed data). Using the NUMPROC(PFD) option can save processing time, but you must use preferred signs with your data for correct processing. NUMPROC(NOPFD) When the NUMPROC(NOPFD) compiler option is in effect, the compiler accepts any valid sign configuration. The preferred sign is always generated in the receiver. NUMPROC(NOPFD) is less efficient than NUMPROC(PFD), but you should use it whenever data that does not use preferred signs might exist. If an unsigned, zoned-decimal sender is moved to an alphanumeric receiver, the sign is unchanged (even with NUMPROC(NOPFD) in effect). NUMPROC(MIG) When NUMPROC(MIG) is in effect, the compiler generates code that is similar to that produced by OS/VS COBOL. This option can be especially useful if you migrate OS/VS COBOL programs to IBM Enterprise COBOL for z/OS.
RELATED REFERENCES

NUMPROC on page 333 ZWB on page 360

Checking for incompatible data (numeric class test)


The compiler assumes that values you supply for a data item are valid for the PICTURE and USAGE clauses, and does not check their validity. Ensure that the contents of a data item conform to the PICTURE and USAGE clauses before using the item in additional processing. It can happen that values are passed into your program and assigned to items that have incompatible data descriptions for those values. For example, nonnumeric data might be moved or passed into a field that is defined as numeric, or a signed number might be passed into a field that is defined as unsigned. In either case, the receiving fields contain invalid data. When you give an item a value that is incompatible with its data description, references to that item in the PROCEDURE DIVISION are undefined and your results are unpredictable. You can use the numeric class test to perform data validation. For example:
Linkage Section. 01 Count-x Pic 999. . . . Procedure Division Using Count-x. If Count-x is numeric then display "Data is good"

56

Enterprise COBOL for z/OS V4.2 Programming Guide

The numeric class test checks the contents of a data item against a set of values that are valid for the PICTURE and USAGE of the data item. For example, a packed-decimal item is checked for hexadecimal values X0 through X9 in the digit positions and for a valid sign value in the sign position (whether separate or nonseparate). For zoned decimal and packed-decimal items, the numeric class test is affected by the NUMPROC compiler option and the NUMCLS option (which is set at installation time). To determine the NUMCLS setting used at your installation, consult your system programmer. If NUMCLS(PRIM) is in effect at your installation, use the following table to find the values that the compiler considers valid for the sign.
Table 7. NUMCLS(PRIM) and valid signs NUMPROC(NOPFD) Signed Unsigned Separate sign C, D, F F +, NUMPROC(PFD) C, D, +0 (positive zero) F +, -, +0 (positive zero) NUMPROC(MIG) C, D, F F +, -

If NUMCLS(ALT) is in effect at your installation, use the following table to find the values that the compiler considers valid for the sign.
Table 8. NUMCLS(ALT) and valid signs NUMPROC(NOPFD) Signed Unsigned Separate sign A to F F +, NUMPROC(PFD) C, D, +0 (positive zero) F +, -, +0 (positive zero) NUMPROC(MIG) A to F F +, -

RELATED REFERENCES

NUMPROC on page 333

Performing arithmetic
You can use any of several COBOL language features (including COMPUTE, arithmetic expressions, numeric intrinsic functions, and math and date callable services) to perform arithmetic. Your choice depends on whether a feature meets your particular needs. For most common arithmetic evaluations, the COMPUTE statement is appropriate. If you need to use numeric literals, numeric data, or arithmetic operators, you might want to use arithmetic expressions. In places where numeric expressions are allowed, you can save time by using numeric intrinsic functions. Language Environment callable services for mathematical functions and for date and time operations also provide a means of assigning arithmetic results to data items.
RELATED TASKS

Using COMPUTE and other arithmetic statements on page 58


Chapter 3. Working with numbers and arithmetic

57

Using Using Using Using

arithmetic expressions numeric intrinsic functions on page 59 math-oriented callable services on page 60 date callable services on page 62

Using COMPUTE and other arithmetic statements


Use the COMPUTE statement for most arithmetic evaluations rather than ADD, SUBTRACT, MULTIPLY, and DIVIDE statements. Often you can code only one COMPUTE statement instead of several individual arithmetic statements. The COMPUTE statement assigns the result of an arithmetic expression to one or more data items:
Compute z = a + b / c ** d - e Compute x y z = a + b / c ** d - e

Some arithmetic calculations might be more intuitive using arithmetic statements other than COMPUTE. For example:
COMPUTE Compute Increment = Increment + 1 Compute Balance = Balance - Overdraft Compute IncrementOne = IncrementOne + 1 Compute IncrementTwo = IncrementTwo + 1 Compute IncrementThree = IncrementThree + 1 Equivalent arithmetic statements Add 1 to Increment Subtract Overdraft from Balance Add 1 to IncrementOne, IncrementTwo, IncrementThree

You might also prefer to use the DIVIDE statement (with its REMAINDER phrase) for division in which you want to process a remainder. The REM intrinsic function also provides the ability to process a remainder. When you perform arithmetic calculations, you can use national decimal data items as operands just as you use zoned decimal data items. You can also use national floating-point data items as operands just as you use display floating-point operands.
RELATED CONCEPTS

Fixed-point contrasted with floating-point arithmetic on page 64 Appendix A, Intermediate results and arithmetic precision, on page 687
RELATED TASKS

Defining numeric data on page 45

Using arithmetic expressions


You can use arithmetic expressions in many (but not all) places in statements where numeric data items are allowed. For example, you can use arithmetic expressions as comparands in relation conditions:
If (a + b) > (c - d + 5) Then. . .

58

Enterprise COBOL for z/OS V4.2 Programming Guide

Arithmetic expressions can consist of a single numeric literal, a single numeric data item, or a single intrinsic function reference. They can also consist of several of these items connected by arithmetic operators. Arithmetic operators are evaluated in the following order of precedence:
Table 9. Order of evaluation of arithmetic operators Operator Unary + or ** / or * Binary + or Meaning Algebraic sign Exponentiation Division or multiplication Addition or subtraction Order of evaluation First Second Third Last

Operators at the same level of precedence are evaluated from left to right; however, you can use parentheses to change the order of evaluation. Expressions in parentheses are evaluated before the individual operators are evaluated. Parentheses, whether necessary or not, make your program easier to read.
RELATED CONCEPTS

Fixed-point contrasted with floating-point arithmetic on page 64 Appendix A, Intermediate results and arithmetic precision, on page 687

Using numeric intrinsic functions


You can use numeric intrinsic functions only in places where numeric expressions are allowed. These functions can save you time because you dont have to code the many common types of calculations that they provide. Numeric intrinsic functions return a signed numeric value, and are treated as temporary numeric data items. Numeric functions are classified into the following categories: Integer Those that return an integer Floating point Those that return a long (64-bit) or extended-precision (128-bit) floating-point value (depending on whether you compile using the default option ARITH(COMPAT) or using ARITH(EXTEND)) Mixed Those that return an integer, a floating-point value, or a fixed-point number with decimal places, depending on the arguments You can use intrinsic functions to perform several different arithmetic operations, as outlined in the following table.

Chapter 3. Working with numbers and arithmetic

59

Table 10. Numeric intrinsic functions Number handling LENGTH MAX MIN NUMVAL NUMVAL-C ORD-MAX ORD-MIN Date and time CURRENT-DATE DATE-OF-INTEGER DATE-TO-YYYYMMDD DATEVAL DAY-OF-INTEGER DAY-TO-YYYYDDD INTEGER-OF-DATE INTEGER-OF-DAY UNDATE WHEN-COMPILED YEAR-TO-YYYY YEARWINDOW Finance ANNUITY PRESENT-VALUE Mathematics ACOS ASIN ATAN COS FACTORIAL INTEGER INTEGER-PART LOG LOG10 MOD REM SIN SQRT SUM TAN Statistics MEAN MEDIAN MIDRANGE RANDOM RANGE STANDARD-DEVIATION VARIANCE

Examples: numeric intrinsic functions on page 62 You can reference one function as the argument of another. A nested function is evaluated independently of the outer function (except when the compiler determines whether a mixed function should be evaluated using fixed-point or floating-point instructions). You can also nest an arithmetic expression as an argument to a numeric function. For example, in the statement below, there are three function arguments (a, b, and the arithmetic expression (c / d)):
Compute x = Function Sum(a b (c / d))

You can reference all the elements of a table (or array) as function arguments by using the ALL subscript. You can also use the integer special registers as arguments wherever integer arguments are allowed. Many of the capabilities of numeric intrinsic functions are also provided by Language Environment callable services.
RELATED CONCEPTS

Fixed-point contrasted with floating-point arithmetic on page 64 Appendix A, Intermediate results and arithmetic precision, on page 687
RELATED REFERENCES

ARITH on page 306

Using math-oriented callable services


Most COBOL intrinsic functions have corresponding math-oriented callable services that you can use to produce the same results. When you compile with the default option ARITH(COMPAT), COBOL floating-point intrinsic functions return long (64-bit) results. When you compile with option

60

Enterprise COBOL for z/OS V4.2 Programming Guide

ARITH(EXTEND), COBOL floating-point intrinsic functions (with the exception of RANDOM) return extended-precision (128-bit) results. For example (considering the first row of the table below), if you compile using ARITH(COMPAT), CEESDACS returns the same result as ACOS. If you compile using ARITH(EXTEND), CEESQACS returns the same result as ACOS.
Table 11. Compatibility of math intrinsic functions and callable services COBOL intrinsic function ACOS ASIN ATAN COS LOG LOG10 RANDOM REM SIN SQRT TAN
1

Corresponding Corresponding Results same for intrinsic long-precision Language extended-precision Language function and callable Environment callable service Environment callable service service? CEESDACS CEESDASN CEESDATN CEESDCOS CEESDLOG CEESDLG1 CEERAN0 CEESDMOD CEESDSIN CEESDSQT CEESDTAN CEESQACS CEESQASN CEESQATN CEESQCOS CEESQLOG CEESQLG1 none CEESQMOD CEESQSIN CEESQSQT CEESQTAN Yes Yes Yes Yes Yes Yes No Yes Yes Yes Yes

1. RANDOM returns a long (64-bit) floating-point result even if you pass it a 31-digit argument and compile with ARITH(EXTEND).

Both the RANDOM intrinsic function and CEERAN0 service generate random numbers between zero and one. However, because each uses its own algorithm, RANDOM and CEERAN0 produce different random numbers from the same seed. Even for functions that produce the same results, how you use intrinsic functions and Language Environment callable services differs. The rules for the data types required for intrinsic function arguments are less restrictive. For numeric intrinsic functions, you can use arguments that are of any numeric data type. When you invoke a Language Environment callable service with a CALL statement, however, you must ensure that the parameters match the numeric data types (generally COMP-1 or COMP-2) required by that service. The error handling of intrinsic functions and Language Environment callable services sometimes differs. If you pass an explicit feedback token when calling the Language Environment math services, you must check the feedback code after each call and take explicit action to deal with errors. However, if you call with the feedback token explicitly OMITTED, you do not need to check the token; Language Environment automatically signals any errors.
RELATED CONCEPTS

Fixed-point contrasted with floating-point arithmetic on page 64 Appendix A, Intermediate results and arithmetic precision, on page 687
RELATED TASKS

Using Language Environment callable services on page 681

Chapter 3. Working with numbers and arithmetic

61

RELATED REFERENCES

ARITH on page 306

Using date callable services


Both the COBOL date intrinsic functions and the Language Environment date callable services are based on the Gregorian calendar. However, the starting dates can differ depending on the setting of the INTDATE compiler option. When INTDATE(LILIAN) is in effect, COBOL uses October 15, 1582 as day 1. Language Environment always uses October 15, 1582 as day 1. If you use INTDATE(LILIAN), you get equivalent results from COBOL intrinsic functions and Language Environment date callable services. The following table compares the results when INTDATE(LILIAN) is in effect.
Table 12. INTDATE(LILIAN) and compatibility of date intrinsic functions and callable services Language Environment callable COBOL intrinsic function service DATE-OF-INTEGER DAY-OF-INTEGER INTEGER-OF-DATE INTEGER-OF-DATE CEEDATE with picture string YYYYMMDD CEEDATE with picture string YYYYDDD CEEDAYS CEECBLDY Results Compatible Compatible Compatible Incompatible

When the default setting of INTDATE(ANSI) is in effect, COBOL uses January 1, 1601 as day 1. The following table compares the results when INTDATE(ANSI) is in effect.
Table 13. INTDATE(ANSI) and compatibility of date intrinsic functions and callable services Language Environment callable COBOL intrinsic function service INTEGER-OF-DATE DATE-OF-INTEGER DAY-OF-INTEGER INTEGER-OF-DATE CEECBLDY CEEDATE with picture string YYYYMMDD CEEDATE with picture string YYYYDDD CEEDAYS Results Compatible Incompatible Incompatible Incompatible

RELATED TASKS

Using Language Environment callable services on page 681


RELATED REFERENCES

INTDATE on page 325

Examples: numeric intrinsic functions


The following examples and accompanying explanations show intrinsic functions in each of several categories. Where the examples below show zoned decimal data items, national decimal items could instead be used. (Signed national decimal items, however, require that the SIGN SEPARATE clause be in effect.)

62

Enterprise COBOL for z/OS V4.2 Programming Guide

General number handling


Suppose you want to find the maximum value of two prices (represented below as alphanumeric items with dollar signs), put this value into a numeric field in an output record, and determine the length of the output record. You can use NUMVAL-C (a function that returns the numeric value of an alphanumeric or national literal, or an alphanumeric or national data item) and the MAX and LENGTH functions to do so:
01 01 01 01 X Pic 9(2). Price1 Pic x(8) Value "$8000". Price2 Pic x(8) Value "$2000". Output-Record. 05 Product-Name Pic x(20). 05 Product-Number Pic 9(9). 05 Product-Price Pic 9(6). . . . Procedure Division. Compute Product-Price = Function Max (Function Numval-C(Price1) Function Numval-C(Price2)) Compute X = Function Length(Output-Record)

Additionally, to ensure that the contents in Product-Name are in uppercase letters, you can use the following statement:
Move Function Upper-case (Product-Name) to Product-Name

Date and time


The following example shows how to calculate a due date that is 90 days from today. The first eight characters returned by the CURRENT-DATE function represent the date in a four-digit year, two-digit month, and two-digit day format (YYYYMMDD). The date is converted to its integer value; then 90 is added to this value and the integer is converted back to the YYYYMMDD format.
01 YYYYMMDD Pic 9(8). 01 Integer-Form Pic S9(9). . . . Move Function Current-Date(1:8) to YYYYMMDD Compute Integer-Form = Function Integer-of-Date(YYYYMMDD) Add 90 to Integer-Form Compute YYYYMMDD = Function Date-of-Integer(Integer-Form) Display 'Due Date: ' YYYYMMDD

Finance
Business investment decisions frequently require computing the present value of expected future cash inflows to evaluate the profitability of a planned investment. The present value of an amount that you expect to receive at a given time in the future is that amount, which, if invested today at a given interest rate, would accumulate to that future amount. For example, assume that a proposed investment of $1,000 produces a payment stream of $100, $200, and $300 over the next three years, one payment per year respectively. The following COBOL statements calculate the present value of those cash inflows at a 10% interest rate:
01 01 01 01 01 . . Series-Amt1 Series-Amt2 Series-Amt3 Discount-Rate Todays-Value . Pic Pic Pic Pic Pic 9(9)V99 9(9)V99 9(9)V99 S9(2)V9(6) 9(9)V99. Value Value Value Value 100. 200. 300. .10.

Chapter 3. Working with numbers and arithmetic

63

Compute Todays-Value = Function Present-Value(Discount-Rate Series-Amt1 Series-Amt2 Series-Amt3)

You can use the ANNUITY function in business problems that require you to determine the amount of an installment payment (annuity) necessary to repay the principal and interest of a loan. The series of payments is characterized by an equal amount each period, periods of equal length, and an equal interest rate each period. The following example shows how you can calculate the monthly payment required to repay a $15,000 loan in three years at a 12% annual interest rate (36 monthly payments, interest per month = .12/12):
01 01 01 01 . . Loan Pic 9(9)V99. Payment Pic 9(9)V99. Interest Pic 9(9)V99. Number-Periods Pic 99. . Compute Loan = 15000 Compute Interest = .12 Compute Number-Periods = 36 Compute Payment = Loan * Function Annuity((Interest / 12) Number-Periods)

Mathematics
The following COBOL statement demonstrates that you can nest intrinsic functions, use arithmetic expressions as arguments, and perform previously complex calculations simply:
Compute Z = Function Log(Function Sqrt (2 * X + 1)) + Function Rem(X 2)

Here in the addend the intrinsic function REM (instead of a DIVIDE statement with a REMAINDER clause) returns the remainder of dividing X by 2.

Statistics
Intrinsic functions make calculating statistical information easier. Assume you are analyzing various city taxes and want to calculate the mean, median, and range (the difference between the maximum and minimum taxes):
01 01 01 01 01 01 01 . . Tax-S Pic Tax-T Pic Tax-W Pic Tax-B Pic Ave-Tax Pic Median-Tax Pic Tax-Range Pic . Compute Ave-Tax = Compute Median-Tax = Compute Tax-Range = 99v999 value 99v999 value 99v999 value 99v999 value 99v999. 99v999. 99v999. .045. .02. .035. .03.

Function Mean (Tax-S Tax-T Tax-W Tax-B) Function Median (Tax-S Tax-T Tax-W Tax-B) Function Range (Tax-S Tax-T Tax-W Tax-B)

RELATED TASKS

Converting to numbers (NUMVAL, NUMVAL-C) on page 113

Fixed-point contrasted with floating-point arithmetic


How you code arithmetic in a program (whether an arithmetic statement, an intrinsic function, an expression, or some combination of these nested within each other) determines whether the evaluation is done with floating-point or fixed-point arithmetic.

64

Enterprise COBOL for z/OS V4.2 Programming Guide

Many statements in a program could involve arithmetic. For example, each of the following types of COBOL statements requires some arithmetic evaluation: v General arithmetic
compute report-matrix-col = (emp-count ** .5) + 1 add report-matrix-min to report-matrix-max giving report-matrix-tot

v Expressions and functions


compute report-matrix-col = function sqrt(emp-count) + 1 compute whole-hours = function integer-part((average-hours) + 1)

v Arithmetic comparisons
if report-matrix-col < function sqrt(emp-count) + 1 if whole-hours not = function integer-part((average-hours) + 1)

Floating-point evaluations
In general, if your arithmetic coding has either of the characteristics listed below, it is evaluated in floating-point arithmetic: v An operand or result field is floating point. An operand is floating point if you code it as a floating-point literal or if you code it as a data item that is defined as USAGE COMP-1, USAGE COMP-2, or external floating point (USAGE DISPLAY or USAGE NATIONAL with a floating-point PICTURE). An operand that is a nested arithmetic expression or a reference to a numeric intrinsic function results in floating-point arithmetic when any of the following conditions is true: An argument in an arithmetic expression results in floating point. The function is a floating-point function. The function is a mixed function with one or more floating-point arguments. v An exponent contains decimal places. An exponent contains decimal places if you use a literal that contains decimal places, give the item a PICTURE that contains decimal places, or use an arithmetic expression or function whose result has decimal places. An arithmetic expression or numeric function yields a result that has decimal places if any operand or argument (excluding divisors and exponents) has decimal places.

Fixed-point evaluations
In general, if an arithmetic operation contains neither of the characteristics listed above for floating point, the compiler causes it to be evaluated in fixed-point arithmetic. In other words, arithmetic evaluations are handled as fixed point only if all the operands are fixed point, the result field is defined to be fixed point, and none of the exponents represent values with decimal places. Nested arithmetic expressions and function references must also represent fixed-point values.

Arithmetic comparisons (relation conditions)


When you compare numeric expressions using a relational operator, the numeric expressions (whether they are data items, arithmetic expressions, function references, or some combination of these) are comparands in the context of the entire evaluation. That is, the attributes of each can influence the evaluation of the other: both expressions are evaluated in fixed point, or both are evaluated in

Chapter 3. Working with numbers and arithmetic

65

floating point. This is also true of abbreviated comparisons even though one comparand does not explicitly appear in the comparison. For example:
if (a + d) = (b + e) and c

This statement has two comparisons: (a + d) = (b + e), and (a + d) = c. Although (a + d) does not explicitly appear in the second comparison, it is a comparand in that comparison. Therefore, the attributes of c can influence the evaluation of (a + d). The compiler handles comparisons (and the evaluation of any arithmetic expressions nested in comparisons) in floating-point arithmetic if either comparand is a floating-point value or resolves to a floating-point value. The compiler handles comparisons (and the evaluation of any arithmetic expressions nested in comparisons) in fixed-point arithmetic if both comparands are fixed-point values or resolve to fixed-point values. Implicit comparisons (no relational operator used) are not handled as a unit, however; the two comparands are treated separately as to their evaluation in floating-point or fixed-point arithmetic. In the following example, five arithmetic expressions are evaluated independently of one anothers attributes, and then are compared to each other.
evaluate (a + d) when (b + e) thru c when (f / g) thru (h * i) . . . end-evaluate

Examples: fixed-point and floating-point evaluations


RELATED REFERENCES

Arithmetic expressions in nonarithmetic statements on page 695

Examples: fixed-point and floating-point evaluations


The following example shows statements that are evaluated using fixed-point arithmetic and using floating-point arithmetic. Assume that you define the data items for an employee table in the following manner:
01 employee-table. 05 emp-count pic 9(4). 05 employee-record occurs 1 to 1000 times depending on emp-count. 10 hours pic +9(5)e+99. . report-matrix-col pic 9(3). report-matrix-min pic 9(3). report-matrix-max pic 9(3). report-matrix-tot pic 9(3). average-hours pic 9(3)v9. whole-hours pic 9(4).

. . 01 01 01 01 01 01

These statements are evaluated using floating-point arithmetic:


compute report-matrix-col = (emp-count ** .5) + 1 compute report-matrix-col = function sqrt(emp-count) + 1 if report-matrix-tot < function sqrt(emp-count) + 1

These statements are evaluated using fixed-point arithmetic:

66

Enterprise COBOL for z/OS V4.2 Programming Guide

add report-matrix-min to report-matrix-max giving report-matrix-tot compute report-matrix-max = function max(report-matrix-max report-matrix-tot) if whole-hours not = function integer-part((average-hours) + 1)

Using currency signs


Many programs need to process financial information and present that information using the appropriate currency signs. With COBOL currency support (and the appropriate code page for your printer or display unit), you can use several currency signs in a program. You can use one or more of the following signs: v Symbols such as the dollar sign ($) v Currency signs of more than one character (such as USD or EUR) v Euro sign, established by the Economic and Monetary Union (EMU) To specify the symbols for displaying financial information, use the CURRENCY SIGN clause (in the SPECIAL-NAMES paragraph in the CONFIGURATION SECTION) with the PICTURE characters that relate to those symbols. In the following example, the PICTURE character $ indicates that the currency sign $US is to be used:
Currency Sign is "$US" with Picture Symbol "$". . . . 77 Invoice-Amount Pic $$,$$9.99. . . . Display "Invoice amount is " Invoice-Amount.

In this example, if Invoice-Amount contained 1500.00, the display output would be:
Invoice amount is $US1,500.00

By using more than one CURRENCY SIGN clause in your program, you can allow for multiple currency signs to be displayed. You can use a hexadecimal literal to indicate the currency sign value. Using a hexadecimal literal could be useful if the data-entry method for the source program does not allow the entry of the intended characters easily. The following example shows the hexadecimal value X'9F' used as the currency sign:
Currency Sign X'9F' with Picture Symbol 'U'. . . . 01 Deposit-Amount Pic UUUUU9.99.

If there is no corresponding character for the euro sign on your keyboard, you need to specify it as a hexadecimal value in the CURRENCY SIGN clause. The hexadecimal value for the euro sign is either X'9F' or X'5A' depending on the code page in use, as shown in the following table.
Table 14. Hexadecimal values of the euro sign Code page CCSID 1140 1141 1142 1143 Applicable countries Modified from Euro sign X9F X9F X5A X5A

USA, Canada, Netherlands, Portugal, Australia, 037 New Zealand Austria, Germany Denmark, Norway Finland, Sweden 273 277 278

Chapter 3. Working with numbers and arithmetic

67

Table 14. Hexadecimal values of the euro sign (continued) Code page CCSID 1144 1145 1146 1147 1148 1149 Applicable countries Italy Spain, Latin America - Spanish UK France Belgium, Canada, Switzerland Iceland Modified from 280 284 285 297 500 871 Euro sign X9F X9F X9F X9F X9F X9F

RELATED REFERENCES

CURRENCY on page 313 CURRENCY SIGN clause (Enterprise COBOL Language Reference)

Example: multiple currency signs


The following example shows how you can display values in both euro currency (as EUR) and Swiss francs (as CHF).
IDENTIFICATION DIVISION. PROGRAM-ID. EuroSamp. Environment Division. Configuration Section. Special-Names. Currency Sign is "CHF " with Picture Symbol "F" Currency Sign is "EUR " with Picture Symbol "U". Data Division. Working-Storage Section. 01 Deposit-in-Euro Pic S9999V99 Value 8000.00. 01 Deposit-in-CHF Pic S99999V99. 01 Deposit-Report. 02 Report-in-Franc Pic -FFFFF9.99. 02 Report-in-Euro Pic -UUUUU9.99. 01 EUR-to-CHF-Conv-Rate Pic 9V99999 Value 1.53893. . . . PROCEDURE DIVISION. Report-Deposit-in-CHF-and-EUR. Move Deposit-in-Euro to Report-in-Euro Compute Deposit-in-CHF Rounded = Deposit-in-Euro * EUR-to-CHF-Conv-Rate On Size Error Perform Conversion-Error Not On Size Error Move Deposit-in-CHF to Report-in-Franc Display "Deposit in euro = " Report-in-Euro Display "Deposit in franc = " Report-in-Franc End-Compute Goback. Conversion-Error. Display "Conversion error from EUR to CHF" Display "Euro value: " Report-in-Euro.

The above example produces the following display output:


Deposit in euro = EUR 8000.00 Deposit in franc = CHF 12311.44

The exchange rate used in this example is for illustrative purposes only.

68

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 4. Handling tables


A table is a collection of data items that have the same description, such as account totals or monthly averages; it consists of a table name and subordinate items called table elements. A table is the COBOL equivalent of an array.

In the example above, SAMPLE-TABLE-ONE is the group item that contains the table. TABLE-COLUMN names the table element of a one-dimensional table that occurs three times. Rather than defining repetitious items as separate, consecutive entries in the DATA DIVISION, you use the OCCURS clause in the DATA DIVISION entry to define a table. This practice has these advantages: v The code clearly shows the unity of the items (the table elements). v You can use subscripts and indexes to refer to the table elements. v You can easily repeat data items. Tables are important for increasing the speed of a program, especially one that looks up records.
RELATED TASKS

Nesting tables on page 71 Defining a table (OCCURS) Referring to an item in a table on page 72 Putting values into a table on page 75 Creating variable-length tables (DEPENDING ON) on page 81 Searching a table on page 84 Processing table items using intrinsic functions on page 86 Handling tables efficiently on page 665

Defining a table (OCCURS)


To code a table, give the table a group name and define a subordinate item (the table element) to be repeated n times.
01 table-name. 05 element-name OCCURS n TIMES. . . . (subordinate items of the table element)

In the example above, table-name is the name of an alphanumeric group item. The table element definition (which includes the OCCURS clause) is subordinate to the group item that contains the table. The OCCURS clause cannot appear in a level-01 description.

Copyright IBM Corp. 1991, 2009

69

If a table is to contain only Unicode (UTF-16) data, and you want the group item that contains the table to behave like an elementary category national item in most operations, code the GROUP-USAGE NATIONAL clause for the group item:
01 table-nameN Group-Usage National. 05 element-nameN OCCURS m TIMES. 10 elementN1 Pic nn. 10 elementN2 Pic S99 Sign Is Leading, Separate. . . .

Any elementary item that is subordinate to a national group must be explicitly or implicitly described as USAGE NATIONAL, and any subordinate numeric data item that is signed must be implicitly or explicitly described with the SIGN IS SEPARATE clause. To create tables of two to seven dimensions, use nested OCCURS clauses. To create a variable-length table, code the DEPENDING ON phrase of the OCCURS clause. To specify that table elements will be arranged in ascending or descending order based on the values in one or more key fields of the table, code the ASCENDING or DESCENDING KEY phrases of the OCCURS clause, or both. Specify the names of the keys in decreasing order of significance. Keys can be of class alphabetic, alphanumeric, DBCS, national, or numeric. (If it has USAGE NATIONAL, a key can be of category national, or can be a national-edited, numeric-edited, national decimal, or national floating-point item.) You must code the ASCENDING or DESCENDING KEY phrase of the OCCURS clause to do a binary search (SEARCH ALL) of a table. Example: binary search on page 86
RELATED CONCEPTS

National groups on page 129


RELATED TASKS

Nesting tables on page 71 Referring to an item in a table on page 72 Putting values into a table on page 75 Creating variable-length tables (DEPENDING ON) on page 81 Using national groups on page 130 Doing a binary search (SEARCH ALL) on page 85 Defining numeric data on page 45
RELATED REFERENCES

OCCURS clause (Enterprise COBOL Language Reference) SIGN clause (Enterprise COBOL Language Reference) ASCENDING KEY and DESCENDING KEY phrases (Enterprise COBOL Language Reference)

70

Enterprise COBOL for z/OS V4.2 Programming Guide

Nesting tables
To create a two-dimensional table, define a one-dimensional table in each occurrence of another one-dimensional table.

For example, in SAMPLE-TABLE-TWO above, TABLE-ROW is an element of a one-dimensional table that occurs two times. TABLE-COLUMN is an element of a two-dimensional table that occurs three times in each occurrence of TABLE-ROW. To create a three-dimensional table, define a one-dimensional table in each occurrence of another one-dimensional table, which is itself contained in each occurrence of another one-dimensional table. For example:

In SAMPLE-TABLE-THREE, TABLE-DEPTH is an element of a one-dimensional table that occurs two times. TABLE-ROW is an element of a two-dimensional table that occurs two times within each occurrence of TABLE-DEPTH. TABLE-COLUMN is an element of a three-dimensional table that occurs three times within each occurrence of TABLE-ROW. In a two-dimensional table, the two subscripts correspond to the row and column numbers. In a three-dimensional table, the three subscripts correspond to the depth, row, and column numbers. Example: subscripting on page 72 Example: indexing on page 72
RELATED TASKS

Defining a table (OCCURS) on page 69 Referring to an item in a table on page 72 Putting values into a table on page 75 Creating variable-length tables (DEPENDING ON) on page 81 Searching a table on page 84 Processing table items using intrinsic functions on page 86 Handling tables efficiently on page 665
RELATED REFERENCES

OCCURS clause (Enterprise COBOL Language Reference)


Chapter 4. Handling tables

71

Example: subscripting
The following example shows valid references to SAMPLE-TABLE-THREE that use literal subscripts. The spaces are required in the second example.
TABLE-COLUMN (2, 2, 1) TABLE-COLUMN (2 2 1)

In either table reference, the first value (2) refers to the second occurrence within TABLE-DEPTH, the second value (2) refers to the second occurrence within TABLE-ROW, and the third value (1) refers to the first occurrence within TABLE-COLUMN. The following reference to SAMPLE-TABLE-TWO uses variable subscripts. The reference is valid if SUB1 and SUB2 are data-names that contain positive integer values within the range of the table.
TABLE-COLUMN (SUB1 SUB2)
RELATED TASKS

Subscripting on page 73

Example: indexing
The following example shows how displacements to elements that are referenced with indexes are calculated. Consider the following three-dimensional table, SAMPLE-TABLE-FOUR:
01 SAMPLE-TABLE-FOUR 05 TABLE-DEPTH OCCURS 3 TIMES INDEXED BY INX-A. 10 TABLE-ROW OCCURS 4 TIMES INDEXED BY INX-B. 15 TABLE-COLUMN OCCURS 8 TIMES INDEXED BY INX-C

PIC X(8).

Suppose you code the following relative indexing reference to SAMPLE-TABLE-FOUR:


TABLE-COLUMN (INX-A + 1, INX-B + 2, INX-C - 1)

This reference causes the following computation of the displacement to the TABLE-COLUMN element:
(contents of INX-A) + (256 * 1) + (contents of INX-B) + (64 * 2) + (contents of INX-C) - (8 * 1)

This calculation is based on the following element lengths: v Each occurrence of TABLE-DEPTH is 256 bytes in length (4 * 8 * 8). v Each occurrence of TABLE-ROW is 64 bytes in length (8 * 8). v Each occurrence of TABLE-COLUMN is 8 bytes in length.
RELATED TASKS

Indexing on page 74

Referring to an item in a table


A table element has a collective name, but the individual items within it do not have unique data-names. To refer to an item, you have a choice of three techniques:

72

Enterprise COBOL for z/OS V4.2 Programming Guide

v Use the data-name of the table element, along with its occurrence number (called a subscript) in parentheses. This technique is called subscripting. v Use the data-name of the table element, along with a value (called an index) that is added to the address of the table to locate an item (as a displacement from the beginning of the table). This technique is called indexing, or subscripting using index-names. v Use both subscripts and indexes together.
RELATED TASKS

Subscripting Indexing on page 74

Subscripting
The lowest possible subscript value is 1, which references the first occurrence of a table element. In a one-dimensional table, the subscript corresponds to the row number. You can use a literal or a data-name as a subscript. If a data item that has a literal subscript is of fixed length, the compiler resolves the location of the data item. When you use a data-name as a variable subscript, you must describe the data-name as an elementary numeric integer. The most efficient format is COMPUTATIONAL (COMP) with a PICTURE size that is smaller than five digits. You cannot use a subscript with a data-name that is used as a subscript. The code generated for the application resolves the location of a variable subscript at run time. You can increment or decrement a literal or variable subscript by a specified integer amount. For example:
TABLE-COLUMN (SUB1 - 1, SUB2 + 3)

You can change part of a table element rather than the whole element. To do so, refer to the character position and length of the substring to be changed. For example:
01 ANY-TABLE. 05 TABLE-ELEMENT PIC X(10) OCCURS 3 TIMES VALUE "ABCDEFGHIJ". . . . MOVE "??" TO TABLE-ELEMENT (1) (3 : 2).

The MOVE statement in the example above moves the string ?? into table element number 1, beginning at character position 3, for a length of 2 characters.

Example: subscripting on page 72


RELATED TASKS

Indexing on page 74
Chapter 4. Handling tables

73

Putting values into a table on page 75 Searching a table on page 84 Handling tables efficiently on page 665

Indexing
You create an index by using the INDEXED BY phrase of the OCCURS clause to identify an index-name. For example, INX-A in the following code is an index-name:
05 TABLE-ITEM PIC X(8) OCCURS 10 INDEXED BY INX-A.

The compiler calculates the value contained in the index as the occurrence number (subscript) minus 1, multiplied by the length of the table element. Therefore, for the fifth occurrence of TABLE-ITEM, the binary value contained in INX-A is (5 - 1) * 8, or 32. You can use an index-name to reference another table only if both table descriptions have the same number of table elements, and the table elements are of the same length. You can use the USAGE IS INDEX clause to create an index data item, and can use an index data item with any table. For example, INX-B in the following code is an index data item:
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-ITEM (INX-A) . . . END-PERFORM.

The index-name INX-A is used to traverse table TABLE-ITEM above. The index data item INX-B is used to hold the index of the last element of the table. The advantage of this type of coding is that calculation of offsets of table elements is minimized, and no conversion is necessary for the UNTIL condition. You can use the SET statement to assign to an index data item the value that you stored in an index-name, as in the statement SET INX-B TO INX-A above. For example, when you load records into a variable-length table, you can store the index value of the last record into a data item defined as USAGE IS INDEX. Then you can test for the end of the table by comparing the current index value with the index value of the last record. This technique is useful when you look through or process a table. You can increment or decrement an index-name by an elementary integer data item or a nonzero integer literal, for example:
SET INX-A DOWN BY 3

The integer represents a number of occurrences. It is converted to an index value before being added to or subtracted from the index.

74

Enterprise COBOL for z/OS V4.2 Programming Guide

Initialize the index-name by using a SET, PERFORM VARYING, or SEARCH ALL statement. You can then use the index-name in SEARCH or relational condition statements. To change the value, use a PERFORM, SEARCH, or SET statement. Because you are comparing a physical displacement, you can directly use index data items only in SEARCH and SET statements or in comparisons with indexes or other index data items. You cannot use index data items as subscripts or indexes. Example: indexing on page 72
RELATED TASKS

Subscripting on page 73 Putting values into a table Searching a table on page 84 Processing table items using intrinsic functions on page 86 Handling tables efficiently on page 665
RELATED REFERENCES

INDEXED BY phrase (Enterprise COBOL Language Reference) INDEX phrase (Enterprise COBOL Language Reference) SET statement (Enterprise COBOL Language Reference)

Putting values into a table


You can put values into a table by loading the table dynamically, initializing the table with the INITIALIZE statement, or assigning values with the VALUE clause when you define the table.
RELATED TASKS

Loading a table dynamically Loading a variable-length table on page 82 Initializing a table (INITIALIZE) on page 76 Assigning values when you define a table (VALUE) on page 77 Assigning values to a variable-length table on page 83

Loading a table dynamically


If the initial values of a table are different with each execution of your program, you can define the table without initial values. You can instead read the changed values into the table dynamically before the program refers to the table. To load a table, use the PERFORM statement and either subscripting or indexing. When reading data to load your table, test to make sure that the data does not exceed the space allocated for the table. Use a named value (rather than a literal) for the maximum item count. Then, if you make the table bigger, you need to change only one value instead of all references to a literal. Example: PERFORM and subscripting on page 79 Example: PERFORM and indexing on page 80
RELATED REFERENCES

PERFORM with VARYING phrase (Enterprise COBOL Language Reference)

Chapter 4. Handling tables

75

Initializing a table (INITIALIZE)


You can load a table by coding one or more INITIALIZE statements. For example, to move the value 3 into each of the elementary numeric data items in a table called TABLE-ONE, shown below, you can code the following statement:
INITIALIZE TABLE-ONE REPLACING NUMERIC DATA BY 3.

To move the character X into each of the elementary alphanumeric data items in TABLE-ONE, you can code the following statement:
INITIALIZE TABLE-ONE REPLACING ALPHANUMERIC DATA BY "X".

When you use the INITIALIZE statement to initialize a table, the table is processed as a group item (that is, with group semantics); elementary data items within the group are recognized and processed. For example, suppose that TABLE-ONE is an alphanumeric group that is defined like this:
01 TABLE-ONE. 02 Trans-out Occurs 20. 05 Trans-code Pic X Value "R". 05 Part-number Pic XX Value "13". 05 Trans-quan Pic 99 Value 10. 05 Price-fields. 10 Unit-price Pic 99V Value 50. 10 Discount Pic 99V Value 25. 10 Sales-Price Pic 999 Value 375. . . . Initialize TABLE-ONE Replacing Numeric Data By 3 Alphanumeric Data By "X"

The table below shows the content that each of the twenty 12-byte elements Trans-out(n) has before execution and after execution of the INITIALIZE statement shown above:
Trans-out(n) before R13105025375 1. The symbol b represents a blank space. Trans-out(n) after XXb0303030031

You can similarly use an INITIALIZE statement to load a table that is defined as a national group. For example, if TABLE-ONE shown above specified the GROUP-USAGE NATIONAL clause, and Trans-code and Part-number had N instead of X in their PICTURE clauses, the following statement would have the same effect as the INITIALIZE statement above, except that the data in TABLE-ONE would instead be encoded in UTF-16:
Initialize TABLE-ONE Replacing Numeric Data By 3 National Data By N"X"

The REPLACING NUMERIC phrase initializes floating-point data items also. You can use the REPLACING phrase of the INITIALIZE statement similarly to initialize all of the elementary ALPHABETIC, DBCS, ALPHANUMERIC-EDITED, NATIONAL-EDITED, and NUMERIC-EDITED data items in a table. The INITIALIZE statement cannot assign values to a variable-length table (that is, a table that was defined using the OCCURS DEPENDING ON clause).

76

Enterprise COBOL for z/OS V4.2 Programming Guide

Examples: initializing data items on page 30


RELATED TASKS

Initializing a structure (INITIALIZE) on page 32 Assigning values when you define a table (VALUE) Assigning values to a variable-length table on page 83 Looping through a table on page 100 Using data items and group items on page 26 Using national groups on page 130
RELATED REFERENCES

INITIALIZE statement (Enterprise COBOL Language Reference)

Assigning values when you define a table (VALUE)


If a table is to contain stable values (such as days and months), you can set the specific values when you define the table. Set static values in tables in one of these ways: v Initialize each table item individually. v Initialize an entire table at the group level. v Initialize all occurrences of a given table element to the same value.
RELATED TASKS

Initializing Initializing Initializing Initializing

each table item individually a table at the group level on page 78 all occurrences of a given table element on page 78 a structure (INITIALIZE) on page 32

Initializing each table item individually


If a table is small, you can set the value of each item individually by using a VALUE clause. Use the following technique, which is shown in the example code below: 1. Declare a record (such as Error-Flag-Table below) that contains the items that are to be in the table. 2. Set the initial value of each item in a VALUE clause. 3. Code a REDEFINES entry to make the record into a table.
*********************************************************** *** E R R O R F L A G T A B L E *** *********************************************************** 01 Error-Flag-Table Value Spaces. 88 No-Errors Value Spaces. 05 Type-Error Pic X. 05 Shift-Error Pic X. 05 Home-Code-Error Pic X. 05 Work-Code-Error Pic X. 05 Name-Error Pic X. 05 Initials-Error Pic X. 05 Duplicate-Error Pic X. 05 Not-Found-Error Pic X. 01 Filler Redefines Error-Flag-Table. 05 Error-Flag Occurs 8 Times Indexed By Flag-Index Pic X.

Chapter 4. Handling tables

77

In the example above, the VALUE clause at the 01 level initializes each of the table items to the same value. Each table item could instead be described with its own VALUE clause to initialize that item to a distinct value. To initialize larger tables, use MOVE, PERFORM, or INITIALIZE statements.
RELATED TASKS

Initializing a structure (INITIALIZE) on page 32 Assigning values to a variable-length table on page 83


RELATED REFERENCES

REDEFINES clause (Enterprise COBOL Language Reference) OCCURS clause (Enterprise COBOL Language Reference)

Initializing a table at the group level


Code an alphanumeric or national group data item and assign to it, through the VALUE clause, the contents of the whole table. Then, in a subordinate data item, use an OCCURS clause to define the individual table items. In the following example, the alphanumeric group data item TABLE-ONE uses a VALUE clause that initializes each of the four elements of TABLE-TWO:
01 TABLE-ONE 05 TABLE-TWO OCCURS 4 TIMES VALUE "1234". PIC X.

In the following example, the national group data item Table-OneN uses a VALUE clause that initializes each of the three elements of the subordinate data item Table-TwoN (each of which is implicitly USAGE NATIONAL). Note that you can initialize a national group data item with a VALUE clause that uses an alphanumeric literal, as shown below, or a national literal.
01 Table-OneN Group-Usage National Value "AB12CD34EF56". 05 Table-TwoN Occurs 3 Times Indexed By MyI. 10 ElementOneN Pic nn. 10 ElementTwoN Pic 99.

After Table-OneN is initialized, ElementOneN(1) contains NX"00410042" (the UTF-16 representation of AB), the national decimal item ElementTwoN(1) contains NX"00310032" (the UTF-16 representation of 12), and so forth.
RELATED REFERENCES

OCCURS clause (Enterprise COBOL Language Reference) GROUP-USAGE clause (Enterprise COBOL Language Reference)

Initializing all occurrences of a given table element


You can use the VALUE clause in the data description of a table element to initialize all instances of that element to the specified value.
01 T2. 05 T-OBJ PIC 9 05 T OCCURS 5 TIMES DEPENDING ON T-OBJ. 10 X PIC XX 10 Y PIC 99 10 Z PIC XX VALUE 3. VALUE "AA". VALUE 19. VALUE "BB".

For example, the code above causes all the X elements (1 through 5) to be initialized to AA, all the Y elements (1 through 5) to be initialized to 19, and all the Z elements (1 through 5) to be initialized to BB. T-OBJ is then set to 3.

78

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED TASKS

Assigning values to a variable-length table on page 83


RELATED REFERENCES

OCCURS clause (Enterprise COBOL Language Reference)

Example: PERFORM and subscripting


This example traverses an error-flag table using subscripting until an error code that has been set is found. If an error code is found, the corresponding error message is moved to a print report field.
*********************************************************** *** E R R O R F L A G T A B L E *** *********************************************************** 01 Error-Flag-Table Value Spaces. 88 No-Errors Value Spaces. 05 Type-Error Pic X. 05 Shift-Error Pic X. 05 Home-Code-Error Pic X. 05 Work-Code-Error Pic X. 05 Name-Error Pic X. 05 Initials-Error Pic X. 05 Duplicate-Error Pic X. 05 Not-Found-Error Pic X. 01 Filler Redefines Error-Flag-Table. 05 Error-Flag Occurs 8 Times Indexed By Flag-Index Pic X. 77 Error-on Pic X Value "E". *********************************************************** *** E R R O R M E S S A G E T A B L E *** *********************************************************** 01 Error-Message-Table. 05 Filler Pic X(25) Value "Transaction Type Invalid". 05 Filler Pic X(25) Value "Shift Code Invalid". 05 Filler Pic X(25) Value "Home Location Code Inval.". 05 Filler Pic X(25) Value "Work Location Code Inval.". 05 Filler Pic X(25) Value "Last Name - Blanks". 05 Filler Pic X(25) Value "Initials - Blanks". 05 Filler Pic X(25) Value "Duplicate Record Found". 05 Filler Pic X(25) Value "Commuter Record Not Found". 01 Filler Redefines Error-Message-Table. 05 Error-Message Occurs 8 Times Indexed By Message-Index Pic X(25). . . . PROCEDURE DIVISION. . . . Perform Varying Sub From 1 By 1 Until No-Errors If Error-Flag (Sub) = Error-On Move Space To Error-Flag (Sub) Move Error-Message (Sub) To Print-Message Perform 260-Print-Report End-If End-Perform . . .
Chapter 4. Handling tables

79

Example: PERFORM and indexing


This example traverses an error-flag table using indexing until an error code that has been set is found. If an error code is found, the corresponding error message is moved to a print report field.
*********************************************************** *** E R R O R F L A G T A B L E *** *********************************************************** 01 Error-Flag-Table Value Spaces. 88 No-Errors Value Spaces. 05 Type-Error Pic X. 05 Shift-Error Pic X. 05 Home-Code-Error Pic X. 05 Work-Code-Error Pic X. 05 Name-Error Pic X. 05 Initials-Error Pic X. 05 Duplicate-Error Pic X. 05 Not-Found-Error Pic X. 01 Filler Redefines Error-Flag-Table. 05 Error-Flag Occurs 8 Times Indexed By Flag-Index Pic X. 77 Error-on Pic X Value "E". *********************************************************** *** E R R O R M E S S A G E T A B L E *** *********************************************************** 01 Error-Message-Table. 05 Filler Pic X(25) Value "Transaction Type Invalid". 05 Filler Pic X(25) Value "Shift Code Invalid". 05 Filler Pic X(25) Value "Home Location Code Inval.". 05 Filler Pic X(25) Value "Work Location Code Inval.". 05 Filler Pic X(25) Value "Last Name - Blanks". 05 Filler Pic X(25) Value "Initials - Blanks". 05 Filler Pic X(25) Value "Duplicate Record Found". 05 Filler Pic X(25) Value "Commuter Record Not Found". 01 Filler Redefines Error-Message-Table. 05 Error-Message Occurs 8 Times Indexed By Message-Index Pic X(25). . . . PROCEDURE DIVISION. . . . Set Flag-Index To 1 Perform Until No-Errors Search Error-Flag When Error-Flag (Flag-Index) = Error-On Move Space To Error-Flag (Flag-Index) Set Message-Index To Flag-Index Move Error-Message (Message-Index) To Print-Message Perform 260-Print-Report End-Search End-Perform . . .

80

Enterprise COBOL for z/OS V4.2 Programming Guide

Creating variable-length tables (DEPENDING ON)


If you do not know before run time how many times a table element occurs, define a variable-length table. To do so, use the OCCURS DEPENDING ON (ODO) clause.
X OCCURS 1 TO 10 TIMES DEPENDING ON Y

In the example above, X is called the ODO subject, and Y is called the ODO object. Two factors affect the successful manipulation of variable-length records: v Correct calculation of record lengths The length of the variable portions of a group item is the product of the object of the DEPENDING ON phrase and the length of the subject of the OCCURS clause. v Conformance of the data in the object of the OCCURS DEPENDING ON clause to its PICTURE clause If the content of the ODO object does not match its PICTURE clause, the program could terminate abnormally. You must ensure that the ODO object correctly specifies the current number of occurrences of table elements. The following example shows a group item (REC-1) that contains both the subject and object of the OCCURS DEPENDING ON clause. The way the length of the group item is determined depends on whether it is sending or receiving data.
WORKING-STORAGE SECTION. 01 MAIN-AREA. 03 REC-1. 05 FIELD-1 05 FIELD-2 OCCURS 1 TO 5 TIMES DEPENDING ON FIELD-1 01 REC-2. 03 REC-2-DATA

PIC 9. PIC X(05). PIC X(50).

If you want to move REC-1 (the sending item in this case) to REC-2, the length of REC-1 is determined immediately before the move, using the current value in FIELD-1. If the content of FIELD-1 conforms to its PICTURE clause (that is, if FIELD-1 contains a zoned decimal item), the move can proceed based on the actual length of REC-1. Otherwise, the result is unpredictable. You must ensure that the ODO object has the correct value before you initiate the move. When you do a move to REC-1 (the receiving item in this case), the length of REC-1 is determined using the maximum number of occurrences. In this example, five occurrences of FIELD-2, plus FIELD-1, yields a length of 26 bytes. In this case, you do not need to set the ODO object (FIELD-1) before referencing REC-1 as a receiving item. However, the sending fields ODO object (not shown) must be set to a valid numeric value between 1 and 5 for the ODO object of the receiving field to be validly set by the move. However, if you do a move to REC-1 (again the receiving item) where REC-1 is followed by a variably located group (a type of complex ODO), the actual length of REC-1 is calculated immediately before the move, using the current value of the ODO object (FIELD-1). In the following example, REC-1 and REC-2 are in the same record, but REC-2 is not subordinate to REC-1 and is therefore variably located:
01 MAIN-AREA 03 REC-1. 05 FIELD-1 05 FIELD-3 05 FIELD-2 OCCURS 1 TO 5 TIMES DEPENDING ON FIELD-1

PIC 9. PIC 9. PIC X(05).


Chapter 4. Handling tables

81

03 REC-2. 05 FIELD-4 OCCURS 1 TO 5 TIMES DEPENDING ON FIELD-3

PIC X(05).

The compiler issues a message that lets you know that the actual length was used. This case requires that you set the value of the ODO object before using the group item as a receiving field. The following example shows how to define a variable-length table when the ODO object (LOCATION-TABLE-LENGTH below) is outside the group:
DATA DIVISION. FILE SECTION. FD LOCATION-FILE RECORDING MODE F BLOCK 0 RECORDS RECORD 80 CHARACTERS LABEL RECORD STANDARD. 01 LOCATION-RECORD. 05 LOC-CODE PIC XX. 05 LOC-DESCRIPTION PIC X(20). 05 FILLER PIC X(58). WORKING-STORAGE SECTION. 01 FLAGS. 05 LOCATION-EOF-FLAG PIC X(5) VALUE SPACE. 88 LOCATION-EOF VALUE "FALSE". 01 MISC-VALUES. 05 LOCATION-TABLE-LENGTH PIC 9(3) VALUE ZERO. 05 LOCATION-TABLE-MAX PIC 9(3) VALUE 100. ***************************************************************** *** L O C A T I O N T A B L E *** *** FILE CONTAINS LOCATION CODES. *** ***************************************************************** 01 LOCATION-TABLE. 05 LOCATION-CODE OCCURS 1 TO 100 TIMES DEPENDING ON LOCATION-TABLE-LENGTH PIC X(80).
RELATED CONCEPTS

Appendix B, Complex OCCURS DEPENDING ON, on page 697


RELATED TASKS

Assigning values to a variable-length table on page 83 Loading a variable-length table Preventing overlay when adding elements to a variable table on page 699 Finding the length of data items on page 118 Enterprise COBOL Compiler and Runtime Migration Guide
RELATED REFERENCES

OCCURS DEPENDING ON clause (Enterprise COBOL Language Reference)

Loading a variable-length table


You can use a do-until structure (a TEST AFTER loop) to control the loading of a variable-length table. For example, after the following code runs, LOCATION-TABLE-LENGTH contains the subscript of the last item in the table.
DATA DIVISION. FILE SECTION. FD LOCATION-FILE RECORDING MODE F BLOCK 0 RECORDS RECORD 80 CHARACTERS LABEL RECORD STANDARD.

82

Enterprise COBOL for z/OS V4.2 Programming Guide

LOCATION-RECORD. 05 LOC-CODE PIC XX. 05 LOC-DESCRIPTION PIC X(20). 05 FILLER PIC X(58). . . . WORKING-STORAGE SECTION. 01 FLAGS. 05 LOCATION-EOF-FLAG PIC X(5) VALUE SPACE. 88 LOCATION-EOF VALUE "YES". 01 MISC-VALUES. 05 LOCATION-TABLE-LENGTH PIC 9(3) VALUE ZERO. 05 LOCATION-TABLE-MAX PIC 9(3) VALUE 100. ***************************************************************** *** L O C A T I O N T A B L E *** *** FILE CONTAINS LOCATION CODES. *** ***************************************************************** 01 LOCATION-TABLE. 05 LOCATION-CODE OCCURS 1 TO 100 TIMES DEPENDING ON LOCATION-TABLE-LENGTH PIC X(80). . . . PROCEDURE DIVISION. . . . Perform Test After Varying Location-Table-Length From 1 By 1 Until Location-EOF Or Location-Table-Length = Location-Table-Max Move Location-Record To Location-Code (Location-Table-Length) Read Location-File At End Set Location-EOF To True End-Read End-Perform

01

Assigning values to a variable-length table


You can code a VALUE clause for an alphanumeric or national group item that has a subordinate data item that contains the OCCURS clause with the DEPENDING ON phrase. Each subordinate structure that contains the DEPENDING ON phrase is initialized using the maximum number of occurrences. If you define the entire table by using the DEPENDING ON phrase, all the elements are initialized using the maximum defined value of the ODO (OCCURS DEPENDING ON) object. If the ODO object is initialized by a VALUE clause, it is logically initialized after the ODO subject has been initialized.
01 TABLE-THREE 05 X 05 Y OCCURS 5 TIMES DEPENDING ON X VALUE "3ABCDE". PIC 9. PIC X.

For example, in the code above, the ODO subject Y(1) is initialized to A, Y(2) to B, . . ., Y(5) to E, and finally the ODO object X is initialized to 3. Any subsequent reference to TABLE-THREE (such as in a DISPLAY statement) refers to X and the first three elements, Y(1) through Y(3), of the table.
RELATED TASKS

Assigning values when you define a table (VALUE) on page 77


RELATED REFERENCES

OCCURS DEPENDING ON clause (Enterprise COBOL Language Reference)


Chapter 4. Handling tables

83

Searching a table
COBOL provides two search techniques for tables: serial and binary. To do serial searches, use SEARCH and indexing. For variable-length tables, you can use PERFORM with subscripting or indexing. To do binary searches, use SEARCH ALL and indexing. A binary search can be considerably more efficient than a serial search. For a serial search, the number of comparisons is of the order of n, the number of entries in the table. For a binary search, the number of comparisons is of the order of only the logarithm (base 2) of n. A binary search, however, requires that the table items already be sorted.
RELATED TASKS

Doing a serial search (SEARCH) Doing a binary search (SEARCH ALL) on page 85

Doing a serial search (SEARCH)


Use the SEARCH statement to do a serial (sequential) search beginning at the current index setting. To modify the index setting, use the SET statement. The conditions in the WHEN phrase are evaluated in the order in which they appear: v If none of the conditions is satisfied, the index is increased to correspond to the next table element, and the WHEN conditions are evaluated again. v If one of the WHEN conditions is satisfied, the search ends. The index remains pointing to the table element that satisfied the condition. v If the entire table has been searched and no conditions were met, the AT END imperative statement is executed if there is one. If you did not code AT END, control passes to the next statement in the program. You can reference only one level of a table (a table element) with each SEARCH statement. To search multiple levels of a table, use nested SEARCH statements. Delimit each nested SEARCH statement with END-SEARCH. Performance: If the found condition comes after some intermediate point in the table, you can speed up the search by using the SET statement to set the index to begin the search after that point. Arranging the table so that the data used most often is at the beginning of the table also enables more efficient serial searching. If the table is large and is presorted, a binary search is more efficient. Example: serial search
RELATED REFERENCES

SEARCH statement (Enterprise COBOL Language Reference)

Example: serial search


The following example shows how you might find a particular string in the innermost table of a three-dimensional table.

84

Enterprise COBOL for z/OS V4.2 Programming Guide

Each dimension of the table has its own index (set to 1, 4, and 1, respectively). The innermost table (TABLE-ENTRY3) has an ascending key.
01 TABLE-ONE. 05 TABLE-ENTRY1 OCCURS 10 TIMES INDEXED BY TE1-INDEX. 10 TABLE-ENTRY2 OCCURS 10 TIMES INDEXED BY TE2-INDEX. 15 TABLE-ENTRY3 OCCURS 5 TIMES ASCENDING KEY IS KEY1 INDEXED BY TE3-INDEX. 20 KEY1 PIC X(5). 20 KEY2 PIC X(10). . . . PROCEDURE DIVISION. . . . SET TE1-INDEX TO 1 SET TE2-INDEX TO 4 SET TE3-INDEX TO 1 MOVE "A1234" TO KEY1 (TE1-INDEX, TE2-INDEX, TE3-INDEX + 2) MOVE "AAAAAAAA00" TO KEY2 (TE1-INDEX, TE2-INDEX, TE3-INDEX + 2) . . . SEARCH TABLE-ENTRY3 AT END MOVE 4 TO RETURN-CODE WHEN TABLE-ENTRY3(TE1-INDEX, TE2-INDEX, TE3-INDEX) = "A1234AAAAAAAA00" MOVE 0 TO RETURN-CODE END-SEARCH

Values after execution:


TE1-INDEX = 1 TE2-INDEX = 4 TE3-INDEX points to the TABLE-ENTRY3 item that equals "A1234AAAAAAAA00" RETURN-CODE = 0

Doing a binary search (SEARCH ALL)


If you use SEARCH ALL to do a binary search, you do not need to set the index before you begin. The index is always the one that is associated with the first index-name in the OCCURS clause. The index varies during execution to maximize the search efficiency. To use the SEARCH ALL statement to search a table, the table must specify the ASCENDING or DESCENDING KEY phrases of the OCCURS clause, or both, and must already be ordered on the key or keys that are specified in the ASCENDING and DESCENDING KEY phrases. In the WHEN phrase of the SEARCH ALL statement, you can test any key that is named in the ASCENDING or DESCENDING KEY phrases for the table, but you must test all preceding keys, if any. The test must be an equal-to condition, and the WHEN phrase must specify either a key (subscripted by the first index-name associated with the table) or a condition-name that is associated with the key. The WHEN condition can be a compound condition that is formed from simple conditions that use AND as the only logical connective. Each key and its object of comparison must be compatible according to the rules for comparison of data items. Note though that if a key is compared to a national literal or identifier, the key must be a national data item.

Chapter 4. Handling tables

85

Example: binary search


RELATED TASKS

Defining a table (OCCURS) on page 69


RELATED REFERENCES

SEARCH statement (Enterprise COBOL Language Reference) General relation conditions (Enterprise COBOL Language Reference)

Example: binary search


The following example shows how you can code a binary search of a table. Suppose you define a table that contains 90 elements of 40 bytes each, and three keys. The primary and secondary keys (KEY-1 and KEY-2) are in ascending order, but the least significant key (KEY-3) is in descending order:
01 TABLE-A. 05 TABLE-ENTRY OCCURS 90 TIMES ASCENDING KEY-1, KEY-2 DESCENDING KEY-3 INDEXED BY INDX-1. 10 PART-1 PIC 99. 10 KEY-1 PIC 9(5). 10 PART-2 PIC 9(6). 10 KEY-2 PIC 9(4). 10 PART-3 PIC 9(18). 10 KEY-3 PIC 9(5).

You can search this table by using the following statements:


SEARCH ALL TABLE-ENTRY AT END PERFORM NOENTRY WHEN KEY-1 (INDX-1) = VALUE-1 AND KEY-2 (INDX-1) = VALUE-2 AND KEY-3 (INDX-1) = VALUE-3 MOVE PART-1 (INDX-1) TO OUTPUT-AREA END-SEARCH

If an entry is found in which each of the three keys is equal to the value to which it is compared (VALUE-1, VALUE-2, and VALUE-3, respectively), PART-1 of that entry is moved to OUTPUT-AREA. If no matching key is found in the entries in TABLE-A, the NOENTRY routine is performed.

Processing table items using intrinsic functions


You can use intrinsic functions to process alphabetic, alphanumeric, national, or numeric table items. (You can process DBCS data items only with the NATIONAL-OF intrinsic function.) The data descriptions of the table items must be compatible with the requirements for the function arguments. Use a subscript or index to reference an individual data item as a function argument. For example, assuming that Table-One is a 3 x 3 array of numeric items, you can find the square root of the middle element by using this statement:
Compute X = Function Sqrt(Table-One(2,2))

You might often need to iteratively process the data in tables. For intrinsic functions that accept multiple arguments, you can use the subscript ALL to

86

Enterprise COBOL for z/OS V4.2 Programming Guide

reference all the items in the table or in a single dimension of the table. The iteration is handled automatically, which can make your code shorter and simpler. You can mix scalars and array arguments for functions that accept multiple arguments:
Compute Table-Median = Function Median(Arg1 Table-One(ALL))

Example: processing tables using intrinsic functions


RELATED TASKS

Using intrinsic functions (built-in functions) on page 40 Converting data items (intrinsic functions) on page 112 Evaluating data items (intrinsic functions) on page 115
RELATED REFERENCES

Intrinsic functions (Enterprise COBOL Language Reference)

Example: processing tables using intrinsic functions


These examples show how you can apply an intrinsic function to some or all of the elements in a table by using the ALL subscript. Assuming that Table-Two is a 2 x 3 x 2 array, the following statement adds the values in elements Table-Two(1,3,1), Table-Two(1,3,2), Table-Two(2,3,1), and Table-Two(2,3,2):
Compute Table-Sum = FUNCTION SUM (Table-Two(ALL, 3, ALL))

The following example computes various salary values for all the employees whose salaries are encoded in Employee-Table:
01 Employee-Table. 05 Emp-Count 05 Emp-Record 10 Emp-Name 10 Emp-Idme 10 Emp-Salary Pic s9(4) usage binary. Occurs 1 to 500 times depending on Emp-Count. Pic x(20). Pic 9(9). Pic 9(7)v99. = = = = = Function Function Function Function Function Max(Emp-Salary(ALL)) Ord-Max(Emp-Salary(ALL)) Mean(Emp-Salary(ALL)) Range(Emp-Salary(ALL)) Sum(Emp-Salary(ALL))

. . . Procedure Division. Compute Max-Salary Compute I Compute Avg-Salary Compute Salary-Range Compute Total-Payroll

Chapter 4. Handling tables

87

88

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 5. Selecting and repeating program actions


Use COBOL control language to choose program actions based on the outcome of logical tests, to iterate over selected parts of your program and data, and to identify statements to be performed as a group. These controls include the IF, EVALUATE, and PERFORM statements, and the use of switches and flags.
RELATED TASKS

Selecting program actions Repeating program actions on page 97

Selecting program actions


You can provide for different program actions depending on the tested value of one or more data items. The IF and EVALUATE statements in COBOL test one or more data items by means of a conditional expression.
RELATED TASKS

Coding a choice of actions Coding conditional expressions on page 94


RELATED REFERENCES

IF statement (Enterprise COBOL Language Reference) EVALUATE statement (Enterprise COBOL Language Reference)

Coding a choice of actions


Use IF . . . ELSE to code a choice between two processing actions. (The word THEN is optional.) Use the EVALUATE statement to code a choice among three or more possible actions.
IF condition-p statement-1 ELSE statement-2 END-IF

When one of two processing choices is no action, code the IF statement with or without ELSE. Because the ELSE clause is optional, you can code the IF statement as follows:
IF condition-q statement-1 END-IF

Such coding is suitable for simple cases. For complex logic, you probably need to use the ELSE clause. For example, suppose you have nested IF statements in which there is an action for only one of the processing choices. You could use the ELSE clause and code the null branch of the IF statement with the CONTINUE statement:

Copyright IBM Corp. 1991, 2009

89

IF condition-q statement-1 ELSE CONTINUE END-IF

The EVALUATE statement is an expanded form of the IF statement that allows you to avoid nesting IF statements, a common source of logic errors and debugging problems.
RELATED TASKS

Using nested IF statements Using the EVALUATE statement on page 91 Coding conditional expressions on page 94

Using nested IF statements


When an IF statement contains an IF statement as one of its possible branches, the IF statements are said to be nested. Theoretically, there is no limit to the depth of nested IF statements. However, use nested IF statements sparingly. The logic can be difficult to follow, although explicit scope terminators and indentation help. When a program has to test a variable for more than two values, EVALUATE is probably a better choice. The following pseudocode depicts a nested IF statement:
IF condition-p IF condition-q statement-1 ELSE statement-2 END-IF statement-3 ELSE statement-4 END-IF

In the pseudocode above, an IF statement and a sequential structure are nested in one branch of the outer IF. In this structure, the END-IF that closes the nested IF is very important. Use END-IF instead of a period, because a period would end the outer IF structure also. The following figure shows the logic structure of the pseudocode above.

90

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED TASKS

Coding a choice of actions on page 89


RELATED REFERENCES

Explicit scope terminators (Enterprise COBOL Language Reference)

Using the EVALUATE statement


You can use the EVALUATE statement instead of a series of nested IF statements to test several conditions and specify a different action for each. Thus you can use the EVALUATE statement to implement a case structure or decision table. You can also use the EVALUATE statement to cause multiple conditions to lead to the same processing, as shown in these examples: Example: EVALUATE using THRU phrase on page 92 Example: EVALUATE using multiple WHEN phrases on page 92 In an EVALUATE statement, the operands before the WHEN phrase are referred to as selection subjects, and the operands in the WHEN phrase are called the selection objects. Selection subjects can be identifiers, literals, conditional expressions, or the word TRUE or FALSE. Selection objects can be identifiers, literals, conditional or arithmetic expressions, or the word TRUE, FALSE, or ANY. You can separate multiple selection subjects with the ALSO phrase. You can separate multiple selection objects with the ALSO phrase. The number of selection objects within each set of selection objects must be equal to the number of selection subjects, as shown in this example: Example: EVALUATE testing several conditions on page 93 Identifiers, literals, or arithmetic expressions that appear within a selection object must be valid operands for comparison to the corresponding operand in the set of selection subjects. Conditions or the word TRUE or FALSE that appear in a selection
Chapter 5. Selecting and repeating program actions

91

object must correspond to a conditional expression or the word TRUE or FALSE in the set of selection subjects. (You can use the word ANY as a selection object to correspond to any type of selection subject.) The execution of the EVALUATE statement ends when one of the following conditions occurs: v The statements associated with the selected WHEN phrase are performed. v The statements associated with the WHEN OTHER phrase are performed. v No WHEN conditions are satisfied. WHEN phrases are tested in the order that they appear in the source program. Therefore, you should order these phrases for the best performance. First code the WHEN phrase that contains selection objects that are most likely to be satisfied, then the next most likely, and so on. An exception is the WHEN OTHER phrase, which must come last.
RELATED TASKS

Coding a choice of actions on page 89


RELATED REFERENCES

EVALUATE statement (Enterprise COBOL Language Reference) General relation conditions (Enterprise COBOL Language Reference) Example: EVALUATE using THRU phrase: This example shows how you can code several conditions in a range of values to lead to the same processing action by coding the THRU phrase. Operands in a THRU phrase must be of the same class. In this example, CARPOOL-SIZE is the selection subject; 1, 2, and 3 THRU 6 are the selection objects:
EVALUATE CARPOOL-SIZE WHEN 1 MOVE "SINGLE" TO PRINT-CARPOOL-STATUS WHEN 2 MOVE "COUPLE" TO PRINT-CARPOOL-STATUS WHEN 3 THRU 6 MOVE "SMALL GROUP" TO PRINT-CARPOOL STATUS WHEN OTHER MOVE "BIG GROUP" TO PRINT-CARPOOL STATUS END-EVALUATE

The following nested IF statements represent the same logic:


IF CARPOOL-SIZE = 1 THEN MOVE "SINGLE" TO PRINT-CARPOOL-STATUS ELSE IF CARPOOL-SIZE = 2 THEN MOVE "COUPLE" TO PRINT-CARPOOL-STATUS ELSE IF CARPOOL-SIZE >= 3 and CARPOOL-SIZE <= 6 THEN MOVE "SMALL GROUP" TO PRINT-CARPOOL-STATUS ELSE MOVE "BIG GROUP" TO PRINT-CARPOOL-STATUS END-IF END-IF END-IF

Example: EVALUATE using multiple WHEN phrases:

92

Enterprise COBOL for z/OS V4.2 Programming Guide

The following example shows that you can code multiple WHEN phrases if several conditions should lead to the same action. Doing so gives you more flexibility than using only the THRU phrase, because the conditions do not have to evaluate to values in a range nor have the same class.
EVALUATE MARITAL-CODE WHEN "M" ADD 2 TO PEOPLE-COUNT WHEN "S" WHEN "D" WHEN "W" ADD 1 TO PEOPLE-COUNT END-EVALUATE

The following nested IF statements represent the same logic:


IF MARITAL-CODE = "M" THEN ADD 2 TO PEOPLE-COUNT ELSE IF MARITAL-CODE = "S" OR MARITAL-CODE = "D" OR MARITAL-CODE = "W" THEN ADD 1 TO PEOPLE-COUNT END-IF END-IF

Example: EVALUATE testing several conditions: This example shows the use of the ALSO phrase to separate two selection subjects (True ALSO True) and to separate the two corresponding selection objects within each set of selection objects (for example, When A + B < 10 Also C = 10). Both selection objects in a WHEN phrase must satisfy the TRUE, TRUE condition before the associated action is performed. If both objects do not evaluate to TRUE, the next WHEN phrase is processed.
Identification Division. Program-ID. MiniEval. Environment Division. Configuration Section. Source-Computer. IBM-390. Data Division. Working-Storage Section. 01 Age Pic 999. 01 Sex Pic X. 01 Description Pic X(15). 01 A Pic 999. 01 B Pic 9999. 01 C Pic 9999. 01 D Pic 9999. 01 E Pic 99999. 01 F Pic 999999. Procedure Division. PN01. Evaluate True Also True When Age < 13 Also Sex = "M" Move "Young Boy" To Description When Age < 13 Also Sex = "F" Move "Young Girl" To Description When Age > 12 And Age < 20 Also Sex = "M" Move "Teenage Boy" To Description When Age > 12 And Age < 20 Also Sex = "F" Move "Teenage Girl" To Description When Age > 19 Also Sex = "M" Move "Adult Man" To Description When Age > 19 Also Sex = "F"
Chapter 5. Selecting and repeating program actions

93

Move "Adult Woman" To Description When Other Move "Invalid Data" To Description End-Evaluate Evaluate True Also True When A + B < 10 Also C = 10 Move "Case 1" To Description When A + B > 50 Also C = ( D + E ) / F Move "Case 2" To Description When Other Move "Case Other" To Description End-Evaluate Stop Run.

Coding conditional expressions


Using the IF and EVALUATE statements, you can code program actions that will be performed depending on the truth value of a conditional expression. The following are some of the conditions that you can specify: v Relation conditions, such as: Numeric comparisons Alphanumeric comparisons DBCS comparisons National comparisons v Class conditions; for example, to test whether a data item: IS NUMERIC IS ALPHABETIC IS DBCS IS KANJI IS NOT KANJI v Condition-name conditions, to test the value of a conditional variable that you define v Sign conditions, to test whether a numeric operand IS POSITIVE, NEGATIVE, or ZERO v Switch-status conditions, to test the status of UPSI switches that you name in the SPECIAL-NAMES paragraph v Complex conditions, such as: Negated conditions; for example, NOT (A IS EQUAL TO B) Combined conditions (conditions combined with logical operators AND or OR)
RELATED CONCEPTS

Switches and flags on page 95


RELATED TASKS

Defining switches and flags on page 95 Resetting switches and flags on page 96 Checking for incompatible data (numeric class test) on page 56 Comparing national (UTF-16) data on page 139 Testing for valid DBCS characters on page 143
RELATED REFERENCES

General relation conditions (Enterprise COBOL Language Reference)

94

Enterprise COBOL for z/OS V4.2 Programming Guide

Class condition (Enterprise COBOL Language Reference) Rules for condition-name entries (Enterprise COBOL Language Reference) Sign condition (Enterprise COBOL Language Reference) Combined conditions (Enterprise COBOL Language Reference)

Switches and flags


Some program decisions are based on whether the value of a data item is true or false, on or off, yes or no. Control these two-way decisions by using level-88 items with meaningful names (condition-names) to act as switches. Other program decisions depend on the particular value or range of values of a data item. When you use condition-names to give more than just on or off values to a field, the field is generally referred to as a flag. Flags and switches make your code easier to change. If you need to change the values for a condition, you have to change only the value of that level-88 condition-name. For example, suppose a program uses a condition-name to test a field for a given salary range. If the program must be changed to check for a different salary range, you need to change only the value of the condition-name in the DATA DIVISION. You do not need to make changes in the PROCEDURE DIVISION.
RELATED TASKS

Defining switches and flags Resetting switches and flags on page 96

Defining switches and flags


In the DATA DIVISION, define level-88 items that will act as switches or flags, and give them meaningful names. To test for more than two values with flags, assign more than one condition-name to a field by using multiple level-88 items. The reader can easily follow your code if you choose meaningful condition-names and if the values assigned to them have some association with logical values. Example: switches Example: flags on page 96

Example: switches
The following examples show how you can use level-88 items to test for various binary-valued (on-off) conditions in your program. For example, to test for the end-of-file condition for an input file named Transaction-File, you can use the following data definitions:
Working-Storage Section. 01 Switches. 05 Transaction-EOF-Switch 88 Transaction-EOF

Pic X value space. value "y".

The level-88 description says that a condition named Transaction-EOF is turned on when Transaction-EOF-Switch has value y. Referencing Transaction-EOF in the PROCEDURE DIVISION expresses the same condition as testing Transaction-EOF-

Chapter 5. Selecting and repeating program actions

95

Switch = "y". For example, the following statement causes a report to be printed only if Transaction-EOF-Switch has been set to y:
If Transaction-EOF Then Perform Print-Report-Summary-Lines

Example: flags
The following examples show how you can use several level-88 items together with an EVALUATE statement to determine which of several conditions in a program is true. Consider for example a program that updates a master file. The updates are read from a transaction file. The records in the file contain a field that indicates which of the three functions is to be performed: add, change, or delete. In the record description of the input file, code a field for the function code using level-88 items:
01 Transaction-Input Record 05 Transaction-Type 88 Add-Transaction 88 Change-Transaction 88 Delete-Transaction Pic X. Value "A". Value "C". Value "D".

The code in the PROCEDURE DIVISION for testing these condition-names to determine which function is to be performed might look like this:
Evaluate True When Add-Transaction Perform Add-Master-Record-Paragraph When Change-Transaction Perform Update-Existing-Record-Paragraph When Delete-Transaction Perform Delete-Master-Record-Paragraph End-Evaluate

Resetting switches and flags


Throughout your program, you might need to reset switches or flags to the original values they had in their data descriptions. To do so, either use a SET statement or define a data item to move to the switch or flag. When you use the SET condition-name TO TRUE statement, the switch or flag is set to the original value that it was assigned in its data description. For a level-88 item that has multiple values, SET condition-name TO TRUE assigns the first value (A in the example below):
88 Record-is-Active Value "A" "O" "S"

Using the SET statement and meaningful condition-names makes it easier for readers to follow your code. Example: set switch on Example: set switch off on page 97

Example: set switch on


The following examples show how you can set a switch on by coding a SET statement that moves the value TRUE to a level-88 item. For example, the SET statement in the following example has the same effect as coding the statement Move "y" to Transaction-EOF-Switch:

96

Enterprise COBOL for z/OS V4.2 Programming Guide

01

Switches 05 Transaction-EOF-Switch Pic X Value space. 88 Transaction-EOF Value "y". . . . Procedure Division. 000-Do-Main-Logic. Perform 100-Initialize-Paragraph Read Update-Transaction-File At End Set Transaction-EOF to True End-Read

The following example shows how to assign a value to a field in an output record based on the transaction code of an input record:
01 Input-Record. 05 Transaction-Type Pic X(9). 01 Data-Record-Out. 05 Data-Record-Type Pic X. 88 Record-Is-Active Value "A". 88 Record-Is-Suspended Value "S". 88 Record-Is-Deleted Value "D". 05 Key-Field Pic X(5). . . . Procedure Division. Evaluate Transaction-Type of Input-Record When "ACTIVE" Set Record-Is-Active to TRUE When "SUSPENDED" Set Record-Is-Suspended to TRUE When "DELETED" Set Record-Is-Deleted to TRUE End-Evaluate

Example: set switch off


The following example shows how you can set a switch off by coding a MOVE statement that moves a value to a level-88 item. For example, you can use a data item called SWITCH-OFF to set an on-off switch to off, as in the following code, which resets a switch to indicate that end-of-file has not been reached:
01 Switches 05 Transaction-EOF-Switch Pic X Value space. 88 Transaction-EOF Value "y". 01 SWITCH-OFF Pic X Value "n". . . . Procedure Division. . . . Move SWITCH-OFF to Transaction-EOF-Switch

Repeating program actions


Use a PERFORM statement to repeat the same code (that is, loop) either a specified number of times or based on the outcome of a decision. You can also use a PERFORM statement to execute a paragraph and then implicitly return control to the next executable statement. In effect, this PERFORM statement is a way of coding a closed subroutine that you can enter from many different parts of the program. PERFORM statements can be inline or out-of-line.

Chapter 5. Selecting and repeating program actions

97

RELATED TASKS

Choosing inline or out-of-line PERFORM Coding a loop on page 99 Looping through a table on page 100 Executing multiple paragraphs or sections on page 100
RELATED REFERENCES

PERFORM statement (Enterprise COBOL Language Reference)

Choosing inline or out-of-line PERFORM


An inline PERFORM is an imperative statement that is executed in the normal flow of a program; an out-of-line PERFORM entails a branch to a named paragraph and an implicit return from that paragraph. To determine whether to code an inline or out-of-line PERFORM statement, answer the following questions: v Is the PERFORM statement used in several places? Use an out-of-line PERFORM when you want to use the same portion of code in several places in your program. v Which placement of the statement will be easier to read? If the code to be performed is short, an inline PERFORM can be easier to read. But if the code extends over several screens, the logical flow of the program might be clearer if you use an out-of-line PERFORM. (Each paragraph in structured programming should perform one logical function, however.) v What are the efficiency tradeoffs? An inline PERFORM avoids the overhead of branching that occurs with an out-of-line PERFORM. But even out-of-line PERFORM coding can improve code optimization, so efficiency gains should not be overemphasized. In the 1974 COBOL standard, the PERFORM statement is out-of-line and thus requires a branch to a separate paragraph and an implicit return. If the performed paragraph is in the subsequent sequential flow of your program, it is also executed in that logic flow. To avoid this additional execution, place the paragraph outside the normal sequential flow (for example, after the GOBACK) or code a branch around it. The subject of an inline PERFORM is an imperative statement. Therefore, you must code statements (other than imperative statements) within an inline PERFORM with explicit scope terminators. Example: inline PERFORM statement

Example: inline PERFORM statement


This example shows the structure of an inline PERFORM statement that has the required scope terminators and the required END-PERFORM phrase.
Perform 100-Initialize-Paragraph * The following statement is an inline PERFORM: Perform Until Transaction-EOF Read Update-Transaction-File Into WS-Transaction-Record At End Set Transaction-EOF To True Not At End Perform 200-Edit-Update-Transaction If No-Errors Perform 300-Update-Commuter-Record

98

Enterprise COBOL for z/OS V4.2 Programming Guide

Else Perform 400-Print-Transaction-Errors * End-If is a required scope terminator End-If Perform 410-Re-Initialize-Fields * End-Read is a required scope terminator End-Read End-Perform

Coding a loop
Use the PERFORM . . . TIMES statement to execute a paragraph a specified number of times.
PERFORM 010-PROCESS-ONE-MONTH 12 TIMES INSPECT . . .

In the example above, when control reaches the PERFORM statement, the code for the paragraph 010-PROCESS-ONE-MONTH is executed 12 times before control is transferred to the INSPECT statement. Use the PERFORM . . . UNTIL statement to execute a paragraph until a condition you choose is satisfied. You can use either of the following forms:
PERFORM . . . WITH TEST AFTER . . . . UNTIL . . . PERFORM . . . [WITH TEST BEFORE] . . . UNTIL . . .

Use the PERFORM . . . WITH TEST AFTER . . . UNTIL statement if you want to execute the paragraph at least once, and test before any subsequent execution. This statement is equivalent to a do-until structure:

In the following example, the implicit WITH TEST BEFORE phrase provides a do-while structure:
PERFORM 010-PROCESS-ONE-MONTH UNTIL MONTH GREATER THAN 12 INSPECT . . .

When control reaches the PERFORM statement, the condition MONTH GREATER THAN 12 is tested. If the condition is satisfied, control is transferred to the INSPECT statement. If the condition is not satisfied, 010-PROCESS-ONE-MONTH is executed, and the condition is tested again. This cycle continues until the condition tests as true. (To make your program easier to read, you might want to code the WITH TEST BEFORE clause.)

Chapter 5. Selecting and repeating program actions

99

Looping through a table


You can use the PERFORM . . . VARYING statement to initialize a table. In this form of the PERFORM statement, a variable is increased or decreased and tested until a condition is satisfied. Thus you use the PERFORM statement to control looping through a table. You can use either of these forms:
PERFORM . . . WITH TEST AFTER . . . . VARYING . . . UNTIL . . . PERFORM . . . [WITH TEST BEFORE] . . . VARYING . . . UNTIL . . .

The following section of code shows an example of looping through a table to check for invalid data:
PERFORM TEST AFTER VARYING WS-DATA-IX FROM 1 BY 1 UNTIL WS-DATA-IX = 12 IF WS-DATA (WS-DATA-IX) EQUALS SPACES SET SERIOUS-ERROR TO TRUE DISPLAY ELEMENT-NUM-MSG5 END-IF END-PERFORM INSPECT . . .

When control reaches the PERFORM statement above, WS-DATA-IX is set equal to 1 and the PERFORM statement is executed. Then the condition WS-DATA-IX = 12 is tested. If the condition is true, control drops through to the INSPECT statement. If the condition is false, WS-DATA-IX is increased by 1, the PERFORM statement is executed, and the condition is tested again. This cycle of execution and testing continues until WS-DATA-IX is equal to 12. The loop above controls input-checking for the 12 fields of item WS-DATA. Empty fields are not allowed in the application, so the section of code loops and issues error messages as appropriate.

Executing multiple paragraphs or sections


In structured programming, you usually execute a single paragraph. However, you can execute a group of paragraphs, or a single section or group of sections, by coding the PERFORM . . . THRU statement. When you use the PERFORM . . . THRU statement, code a paragraph-EXIT statement to clearly indicate the end point of a series of paragraphs.
RELATED TASKS

Processing table items using intrinsic functions on page 86

100

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 6. Handling strings


COBOL provides language constructs for performing many different operations on string data items. For example, you can: v Join or split data items. v Manipulate null-terminated strings, such as count or move characters. v Refer to substrings by their ordinal position and, if needed, length. v Tally and replace data items, such as count the number of times a specific character occurs in a data item. v Convert data items, such as change to uppercase or lowercase. v Evaluate data items, such as determine the length of a data item.
RELATED TASKS

Joining data items (STRING) Splitting data items (UNSTRING) on page 103 Manipulating null-terminated strings on page 106 Referring to substrings of data items on page 107 Tallying and replacing data items (INSPECT) on page 111 Converting data items (intrinsic functions) on page 112 Evaluating data items (intrinsic functions) on page 115 Chapter 7, Processing data in an international environment, on page 121

Joining data items (STRING)


Use the STRING statement to join all or parts of several data items or literals into one data item. One STRING statement can take the place of several MOVE statements. The STRING statement transfers data into a receiving data item in the order that you indicate. In the STRING statement you also specify: v A delimiter for each set of sending fields that, if encountered, causes those sending fields to stop being transferred (DELIMITED BY phrase) v (Optional) Action to be taken if the receiving field is filled before all of the sending data has been processed (ON OVERFLOW phrase) v (Optional) An integer data item that indicates the leftmost character position within the receiving field into which data should be transferred (WITH POINTER phrase) The receiving data item must not be an edited item, or a display or national floating-point item. If the receiving data item has: v USAGE DISPLAY, each identifier in the statement except the POINTER identifier must have USAGE DISPLAY, and each literal in the statement must be alphanumeric v USAGE NATIONAL, each identifier in the statement except the POINTER identifier must have USAGE NATIONAL, and each literal in the statement must be national v USAGE DISPLAY-1, each identifier in the statement except the POINTER identifier must have USAGE DISPLAY-1, and each literal in the statement must be DBCS

Copyright IBM Corp. 1991, 2009

101

Only that portion of the receiving field into which data is written by the STRING statement is changed. Example: STRING statement
RELATED TASKS

Handling errors in joining and splitting strings on page 234


RELATED REFERENCES

STRING statement (Enterprise COBOL Language Reference)

Example: STRING statement


The following example shows the STRING statement selecting and formatting information from a record into an output line. The FILE SECTION defines the following record:
01 RCD-01. 05 CUST-INFO. 10 CUST-NAME 10 CUST-ADDR 05 BILL-INFO. 10 INV-NO 10 INV-AMT 10 AMT-PAID 10 DATE-PAID 10 BAL-DUE 10 DATE-DUE

PIC X(15). PIC X(35). PIC PIC PIC PIC PIC PIC X(6). $$,$$$.99. $$,$$$.99. X(8). $$,$$$.99. X(8).

The WORKING-STORAGE SECTION defines the following fields:


77 77 77 77 RPT-LINE LINE-POS LINE-NO DEC-POINT PIC PIC PIC PIC X(120). S9(3). 9(5) VALUE 1. X VALUE ".".

The record RCD-01 contains the following information (the symbol b indicates a blank space):
J.B.bSMITHbbbbb 444bSPRINGbST.,bCHICAGO,bILL.bbbbbb A14275 $4,736.85 $2,400.00 09/22/76 $2,336.85 10/22/76

In the PROCEDURE DIVISION, these settings occur before the STRING statement: v RPT-LINE is set to SPACES. v LINE-POS, the data item to be used as the POINTER field, is set to 4. Here is the STRING statement:
STRING LINE-NO SPACE CUST-INFO INV-NO SPACE DATE-DUE SPACE DELIMITED BY SIZE BAL-DUE DELIMITED BY DEC-POINT INTO RPT-LINE WITH POINTER LINE-POS.

102

Enterprise COBOL for z/OS V4.2 Programming Guide

Because the POINTER field LINE-POS has value 4 before the STRING statement is performed, data is moved into the receiving field RPT-LINE beginning at character position 4. Characters in positions 1 through 3 are unchanged. The sending items that specify DELIMITED BY SIZE are moved in their entirety to the receiving field. Because BAL-DUE is delimited by DEC-POINT, the moving of BAL-DUE to the receiving field stops when a decimal point (the value of DEC-POINT) is encountered.

STRING results
When the STRING statement is performed, items are moved into RPT-LINE as shown in the table below.
Item LINE-NO Space CUST-INFO INV-NO Space DATE-DUE Space Portion of BAL-DUE that precedes the decimal point Positions 4-8 9 10 - 59 60 - 65 66 67 - 74 75 76 - 81

After the STRING statement is performed, the value of LINE-POS is 82, and RPT-LINE has the values shown below.

Splitting data items (UNSTRING)


Use the UNSTRING statement to split a sending field into several receiving fields. One UNSTRING statement can take the place of several MOVE statements. In the UNSTRING statement you can specify: v Delimiters that, when one of them is encountered in the sending field, cause the current receiving field to stop receiving and the next, if any, to begin receiving (DELIMITED BY phrase) v A field for the delimiter that, when encountered in the sending field, causes the current receiving field to stop receiving (DELIMITER IN phrase) v An integer data item that stores the number of characters placed in the current receiving field (COUNT IN phrase) v An integer data item that indicates the leftmost character position within the sending field at which UNSTRING processing should begin (WITH POINTER phrase) v An integer data item that stores a tally of the number of receiving fields that are acted on (TALLYING IN phrase)
Chapter 6. Handling strings

103

v Action to be taken if all of the receiving fields are filled before the end of the sending data item is reached (ON OVERFLOW phrase) The sending data item and the delimiters in the DELIMITED BY phrase must be of category alphabetic, alphanumeric, alphanumeric-edited, DBCS, national, or national-edited. Receiving data items can be of category alphabetic, alphanumeric, numeric, DBCS, or national. If numeric, a receiving data item must be zoned decimal or national decimal. If a receiving data item has: v USAGE DISPLAY, the sending item and each delimiter item in the statement must have USAGE DISPLAY, and each literal in the statement must be alphanumeric v USAGE NATIONAL, the sending item and each delimiter item in the statement must have USAGE NATIONAL, and each literal in the statement must be national v USAGE DISPLAY-1, the sending item and each delimiter item in the statement must have USAGE DISPLAY-1, and each literal in the statement must be DBCS Example: UNSTRING statement
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125


RELATED TASKS

Handling errors in joining and splitting strings on page 234


RELATED REFERENCES

UNSTRING statement (Enterprise COBOL Language Reference) Classes and categories of data (Enterprise COBOL Language Reference)

Example: UNSTRING statement


The following example shows the UNSTRING statement transferring selected information from an input record. Some information is organized for printing and some for further processing. The FILE SECTION defines the following records:
* Record to be acted on by the UNSTRING statement: 01 INV-RCD. 05 CONTROL-CHARS PIC XX. 05 ITEM-INDENT PIC X(20). 05 FILLER PIC X. 05 INV-CODE PIC X(10). 05 FILLER PIC X. 05 NO-UNITS PIC 9(6). 05 FILLER PIC X. 05 PRICE-PER-M PIC 99999. 05 FILLER PIC X. 05 RTL-AMT PIC 9(6).99. UNSTRING receiving field for printed output: 01 DISPLAY-REC. 05 INV-NO PIC X(6). 05 FILLER PIC X VALUE SPACE. 05 ITEM-NAME PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 DISPLAY-DOLS PIC 9(6). UNSTRING receiving field for further processing:

* *

* *

104

Enterprise COBOL for z/OS V4.2 Programming Guide

01

WORK-REC. 05 M-UNITS 05 FIELD-A 05 WK-PRICE REDEFINES FIELD-A 05 INV-CLASS

PIC PIC PIC PIC

9(6). 9(6). 9999V99. X(3).

* *

UNSTRING statement control fields: 77 DBY-1 PIC X. 77 CTR-1 PIC S9(3). 77 CTR-2 PIC S9(3). 77 CTR-3 PIC S9(3). 77 CTR-4 PIC S9(3). 77 DLTR-1 PIC X. 77 DLTR-2 PIC X. 77 CHAR-CT PIC S9(3). 77 FLDS-FILLED PIC S9(3).

In the PROCEDURE DIVISION, these settings occur before the UNSTRING statement: v A period (.) is placed in DBY-1 for use as a delimiter. v CHAR-CT (the POINTER field) is set to 3. v The value zero (0) is placed in FLDS-FILLED (the TALLYING field). v Data is read into record INV-RCD, whose format is as shown below.

Here is the UNSTRING statement:


* Move subfields of INV-RCD to the subfields of DISPLAY-REC * and WORK-REC: UNSTRING INV-RCD DELIMITED BY ALL SPACES OR "/" OR DBY-1 INTO ITEM-NAME COUNT IN CTR-1 INV-NO DELIMITER IN DLTR-1 COUNT IN CTR-2 INV-CLASS M-UNITS COUNT IN CTR-3 FIELD-A DISPLAY-DOLS DELIMITER IN DLTR-2 COUNT IN CTR-4 WITH POINTER CHAR-CT TALLYING IN FLDS-FILLED ON OVERFLOW GO TO UNSTRING-COMPLETE.

Because the POINTER field CHAR-CT has value 3 before the UNSTRING statement is performed, the two character positions of the CONTROL-CHARS field in INV-RCD are ignored.

UNSTRING results
When the UNSTRING statement is performed, the following steps take place: 1. Positions 3 through 18 (FOUR-PENNY-NAILS) of INV-RCD are placed in ITEM-NAME, left justified in the area, and the four unused character positions are padded with spaces. The value 16 is placed in CTR-1. 2. Because ALL SPACES is coded as a delimiter, the five contiguous space characters in positions 19 through 23 are considered to be one occurrence of the delimiter. 3. Positions 24 through 29 (707890) are placed in INV-NO. The delimiter character slash (/) is placed in DLTR-1, and the value 6 is placed in CTR-2.
Chapter 6. Handling strings

105

4. Positions 31 through 33 (BBA) are placed in INV-CLASS. The delimiter is SPACE, but because no field has been defined as a receiving area for delimiters, the space in position 34 is bypassed. 5. Positions 35 through 40 (475120) are placed in M-UNITS. The value 6 is placed in CTR-3. The delimiter is SPACE, but because no field has been defined as a receiving area for delimiters, the space in position 41 is bypassed. 6. Positions 42 through 46 (00122) are placed in FIELD-A and right justified in the area. The high-order digit position is filled with a zero (0). The delimiter is SPACE, but because no field was defined as a receiving area for delimiters, the space in position 47 is bypassed. 7. Positions 48 through 53 (000379) are placed in DISPLAY-DOLS. The period (.) delimiter in DBY-1 is placed in DLTR-2, and the value 6 is placed in CTR-4. 8. Because all receiving fields have been acted on and two characters in INV-RCD have not been examined, the ON OVERFLOW statement is executed. Execution of the UNSTRING statement is completed. After the UNSTRING statement is performed, the fields contain the values shown below.
Field DISPLAY-REC WORK-REC CHAR-CT (the POINTER field) FLDS-FILLED (the TALLYING field) Value 707890 FOUR-PENNY-NAILS 475120000122BBA 55 6 000379

Manipulating null-terminated strings


You can construct and manipulate null-terminated strings (for example, strings that are passed to or from a C program) by various mechanisms. For example, you can: v Use null-terminated literal constants (Z". . . "). v Use an INSPECT statement to count the number of characters in a null-terminated string:
MOVE 0 TO char-count INSPECT source-field TALLYING char-count FOR CHARACTERS BEFORE X"00"

v Use an UNSTRING statement to move characters in a null-terminated string to a target field, and get the character count:
WORKING-STORAGE SECTION. 01 source-field PIC X(1001). 01 char-count COMP-5 PIC 9(4). 01 target-area. 02 individual-char OCCURS 1 TO 1000 TIMES DEPENDING ON char-count PIC X. . . . PROCEDURE DIVISION. UNSTRING source-field DELIMITED BY X"00" INTO target-area COUNT IN char-count ON OVERFLOW DISPLAY "source not null terminated or target too short" END-UNSTRING

106

Enterprise COBOL for z/OS V4.2 Programming Guide

v Use a SEARCH statement to locate trailing null or space characters. Define the string being examined as a table of single characters. v Check each character in a field in a loop (PERFORM). You can examine each character in a field by using a reference modifier such as source-field (I:1). Example: null-terminated strings
RELATED TASKS

Handling null-terminated strings on page 470


RELATED REFERENCES

Alphanumeric literals (Enterprise COBOL Language Reference)

Example: null-terminated strings


The following example shows several ways in which you can process null-terminated strings.
01 L pic X(20) value z'ab'. 01 M pic X(20) value z'cd'. 01 N pic X(20). 01 N-Length pic 99 value zero. 01 Y pic X(13) value 'Hello, World!'. . . . * Display null-terminated string: Inspect N tallying N-length for characters before initial x'00' Display 'N: ' N(1:N-Length) ' Length: ' N-Length . . . * Move null-terminated string to alphanumeric, strip null: Unstring N delimited by X'00' into X . . . * Create null-terminated string: String Y delimited by size X'00' delimited by size into N. . . . * Concatenate two null-terminated strings to produce another: String L delimited by x'00' M delimited by x'00' X'00' delimited by size into N.

Referring to substrings of data items


Refer to a substring of a data item that has USAGE DISPLAY, DISPLAY-1, or NATIONAL by using a reference modifier. You can also refer to a substring of an alphanumeric or national character string that is returned by an intrinsic function by using a reference modifier. The following example shows how to use a reference modifier to refer to a twenty-character substring of a data item called Customer-Record:
Move Customer-Record(1:20) to Orig-Customer-Name

You code a reference modifier in parentheses immediately after the data item. As the example shows, a reference modifier can contain two values that are separated by a colon, in this order: 1. Ordinal position (from the left) of the character that you want the substring to start with
Chapter 6. Handling strings

107

2. (Optional) Length of the desired substring in character positions The reference-modifier position and length for an item that has USAGE DISPLAY are expressed in terms of single-byte characters. The reference-modifier position and length for items that have USAGE DISPLAY-1 or NATIONAL are expressed in terms of DBCS character positions and national character positions, respectively. If you omit the length in a reference modifier (coding only the ordinal position of the first character, followed by a colon), the substring extends to the end of the item. Omit the length where possible as a simpler and less error-prone coding technique. You can refer to substrings of USAGE DISPLAY data items, including alphanumeric groups, alphanumeric-edited data items, numeric-edited data items, display floating-point data items, and zoned decimal data items, by using reference modifiers. When you reference-modify any of these data items, the result is of category alphanumeric. When you reference-modify an alphabetic data item, the result is of category alphabetic. You can refer to substrings of USAGE NATIONAL data items, including national groups, national-edited data items, numeric-edited data items, national floating-point data items, and national decimal data items, by using reference modifiers. When you reference-modify any of these data items, the result is of category national. For example, suppose that you define a national decimal data item as follows:
01 NATL-DEC-ITEM Usage National Pic 999 Value 123.

You can use NATL-DEC-ITEM in an arithmetic expression because NATL-DEC-ITEM is of category numeric. But you cannot use NATL-DEC-ITEM(2:1) (the national character 2, which in hexadecimal notation is NX"0032") in an arithmetic expression, because it is of category national. You can refer to substrings of table entries, including variable-length entries, by using reference modifiers. To refer to a substring of a table entry, code the subscript expression before the reference modifier. For example, assume that PRODUCT-TABLE is a properly coded table of character strings. To move D to the fourth character in the second string in the table, you can code this statement:
MOVE 'D' to PRODUCT-TABLE (2), (4:1)

You can code either or both of the two values in a reference modifier as a variable or as an arithmetic expression. Example: arithmetic expressions as reference modifiers on page 110 Because numeric function identifiers can be used anywhere that arithmetic expressions can be used, you can code a numeric function identifier in a reference modifier as the leftmost character position or as the length, or both. Example: intrinsic functions as reference modifiers on page 110 Each number in the reference modifier must have a value of at least 1. The sum of the two numbers must not exceed the total length of the data item by more than 1 character position so that you do not reference beyond the end of the substring.

108

Enterprise COBOL for z/OS V4.2 Programming Guide

If the leftmost character position or the length value is a fixed-point noninteger, truncation occurs to create an integer. If either is a floating-point noninteger, rounding occurs to create an integer. The following options detect out-of-range reference modifiers, and flag violations with a runtime message: v SSRANGE compiler option v CHECK runtime option
RELATED CONCEPTS

Reference modifiers Unicode and the encoding of language characters on page 125
RELATED TASKS

Referring to an item in a table on page 72


RELATED REFERENCES

SSRANGE on page 347 Reference modification (Enterprise COBOL Language Reference) Function definitions (Enterprise COBOL Language Reference)

Reference modifiers
Reference modifiers let you easily refer to a substring of a data item. For example, assume that you want to retrieve the current time from the system and display its value in an expanded format. You can retrieve the current time with the ACCEPT statement, which returns the hours, minutes, seconds, and hundredths of seconds in this format:
HHMMSSss

However, you might prefer to view the current time in this format:
HH:MM:SS

Without reference modifiers, you would have to define data items for both formats. You would also have to write code to convert from one format to the other. With reference modifiers, you do not need to provide names for the subfields that describe the TIME elements. The only data definition you need is for the time as returned by the system. For example:
01 REFMOD-TIME-ITEM PIC X(8).

The following code retrieves and expands the time value:


ACCEPT REFMOD-TIME-ITEM FROM TIME. DISPLAY "CURRENT TIME IS: " Retrieve the portion of the time value that corresponds to the number of hours: REFMOD-TIME-ITEM (1:2) ":" Retrieve the portion of the time value that corresponds to the number of minutes: REFMOD-TIME-ITEM (3:2) ":" Retrieve the portion of the time value that corresponds to the number of seconds: REFMOD-TIME-ITEM (5:2)

* * * * * *

Chapter 6. Handling strings

109

Example: arithmetic expressions as reference modifiers Example: intrinsic functions as reference modifiers
RELATED TASKS

Assigning input from a screen or file (ACCEPT) on page 37 Referring to substrings of data items on page 107 Using national data (Unicode) in COBOL on page 126
RELATED REFERENCES

Reference modification (Enterprise COBOL Language Reference)

Example: arithmetic expressions as reference modifiers


Suppose that a field contains some right-justified characters, and you want to move those characters to another field where they will be left justified. You can do so by using reference modifiers and an INSPECT statement. Suppose a program has the following data:
01 01 01 LEFTY RIGHTY I PIC X(30). PIC X(30) JUSTIFIED RIGHT. PIC 9(9) USAGE BINARY.

The program counts the number of leading spaces and, using arithmetic expressions in a reference modifier, moves the right-justified characters into another field, justified to the left:
MOVE SPACES TO LEFTY MOVE ZERO TO I INSPECT RIGHTY TALLYING I FOR LEADING SPACE. IF I IS LESS THAN LENGTH OF RIGHTY THEN MOVE RIGHTY ( I + 1 : LENGTH OF RIGHTY - I ) TO LEFTY END-IF

The MOVE statement transfers characters from RIGHTY, beginning at the position computed as I + 1 for a length that is computed as LENGTH OF RIGHTY - I, into the field LEFTY.

Example: intrinsic functions as reference modifiers


You can use intrinsic functions in reference modifiers if you do not know the leftmost position or length of a substring at compile time. For example, the following code fragment causes a substring of Customer-Record to be moved into the data item WS-name. The substring is determined at run time.
05 WS-name Pic x(20). 05 Left-posn Pic 99. 05 I Pic 99. . . . Move Customer-Record(Function Min(Left-posn I):Function Length(WS-name)) to WS-name

If you want to use a noninteger function in a position that requires an integer function, you can use the INTEGER or INTEGER-PART function to convert the result to an integer. For example:
Move Customer-Record(Function Integer(Function Sqrt(I)): ) to WS-name
RELATED REFERENCES

INTEGER (Enterprise COBOL Language Reference) INTEGER-PART (Enterprise COBOL Language Reference)

110

Enterprise COBOL for z/OS V4.2 Programming Guide

Tallying and replacing data items (INSPECT)


Use the INSPECT statement to inspect characters or groups of characters in a data item and to optionally replace them. Use the INSPECT statement to do the following tasks: v Count the number of times a specific character occurs in a data item (TALLYING phrase). v Fill a data item or selected portions of a data item with specified characters such as spaces, asterisks, or zeros (REPLACING phrase). v Convert all occurrences of a specific character or string of characters in a data item to replacement characters that you specify (CONVERTING phrase). You can specify one of the following data items as the item to be inspected: v An elementary item described explicitly or implicitly as USAGE DISPLAY, USAGE DISPLAY-1, or USAGE NATIONAL v An alphanumeric group item or national group item If the inspected item has: v USAGE DISPLAY, each identifier in the statement (except the TALLYING count field) must have USAGE DISPLAY, and each literal in the statement must be alphanumeric v USAGE NATIONAL, each identifier in the statement (except the TALLYING count field) must have USAGE NATIONAL, and each literal in the statement must be national v USAGE DISPLAY-1, each identifier in the statement (except the TALLYING count field) must have USAGE DISPLAY-1, and each literal in the statement must be a DBCS literal Examples: INSPECT statement
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125


RELATED REFERENCES

INSPECT statement (Enterprise COBOL Language Reference)

Examples: INSPECT statement


The following examples show some uses of the INSPECT statement to examine and replace characters. In the following example, the INSPECT statement examines and replaces characters in data item DATA-2. The number of times a leading zero (0) occurs in the data item is accumulated in COUNTR. The first instance of the character A that follows the first instance of the character C is replaced by the character 2.
77 COUNTR 01 DATA-2 . . . INSPECT DATA-2 TALLYING COUNTR REPLACING FIRST PIC 9 VALUE ZERO. PIC X(11). FOR LEADING "0" "A" BY "2" AFTER INITIAL "C"

Chapter 6. Handling strings

111

DATA-2 before 00ACADEMY00 0000ALABAMA CHATHAM0000

COUNTR after 2 4 0

DATA-2 after 00AC2DEMY00 0000ALABAMA CH2THAM0000

In the following example, the INSPECT statement examines and replaces characters in data item DATA-3. Each character that precedes the first instance of a quotation mark (") is replaced by the character 0.
77 COUNTR PIC 9 VALUE ZERO. 01 DATA-3 PIC X(8). . . . INSPECT DATA-3 REPLACING CHARACTERS BY ZEROS BEFORE INITIAL QUOTE DATA-3 before 456"ABEL ANDES"12 "TWAS BR COUNTR after 0 0 0 DATA-3 after 000"ABEL 00000"12 "TWAS BR

The following example shows the use of INSPECT CONVERTING with AFTER and BEFORE phrases to examine and replace characters in data item DATA-4. All characters that follow the first instance of the character / but that precede the first instance of the character ? (if any) are translated from lowercase to uppercase.
01 DATA-4 PIC X(11). . . . INSPECT DATA-4 CONVERTING "abcdefghijklmnopqrstuvwxyz" TO "ABCDEFGHIJKLMNOPQRSTUVWXYZ" AFTER INITIAL "/" BEFORE INITIAL"?" DATA-4 before a/five/?six r/Rexx/RRRr zfour?inspe DATA-4 after a/FIVE/?six r/REXX/RRRR zfour?inspe

Converting data items (intrinsic functions)


You can use intrinsic functions to convert character-string data items to several other formats, for example, to uppercase or lowercase, to reverse order, to numbers, or to one code page from another. You can use the NATIONAL-OF and DISPLAY-OF intrinsic functions to convert to and from national (Unicode) strings. You can also use the INSPECT statement to convert characters. Examples: INSPECT statement on page 111

112

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED TASKS

Converting to uppercase or lowercase (UPPER-CASE, LOWER-CASE) Transforming to reverse order (REVERSE) Converting to numbers (NUMVAL, NUMVAL-C) Converting from one code page to another on page 115

Converting to uppercase or lowercase (UPPER-CASE, LOWER-CASE)


You can use the UPPER-CASE and LOWER-CASE intrinsic functions to easily change the case of alphanumeric, alphabetic, or national strings.
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

The code above displays the following messages on the system logical output device:
Hello HELLO hello HELLO World! WORLD! world! WORLD!

The DISPLAY statements do not change the actual contents of Item-1, but affect only how the letters are displayed. However, the MOVE statement causes uppercase letters to replace the contents of Item-2.
RELATED TASKS

Assigning input from a screen or file (ACCEPT) on page 37 Displaying values on a screen or in a file (DISPLAY) on page 38

Transforming to reverse order (REVERSE)


You can reverse the order of the characters in a string by using the REVERSE intrinsic function.
Move Function Reverse(Orig-cust-name) To Orig-cust-name

For example, the statement above reverses the order of the characters in Orig-cust-name. If the starting value is JOHNSONbbb, the value after the statement is performed is bbbNOSNHOJ, where b represents a blank space.
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125

Converting to numbers (NUMVAL, NUMVAL-C)


The NUMVAL and NUMVAL-C functions convert character strings (alphanumeric or national literals, or class alphanumeric or class national data items) to numbers. Use these functions to convert free-format character-representation numbers to numeric form so that you can process them numerically.

Chapter 6. Handling strings

113

01 01 01 . .

R S Total . Compute

Pic x(20) Value "- 1234.5678". Pic x(20) Value " $12,345.67CR". Usage is Comp-1. Total = Function Numval(R) + Function Numval-C(S)

Use NUMVAL-C when the argument includes a currency symbol or comma or both, as shown in the example above. You can also place an algebraic sign before or after the character string, and the sign will be processed. The arguments must not exceed 18 digits when you compile with the default option ARITH(COMPAT) (compatibility mode) nor 31 digits when you compile with ARITH(EXTEND) (extended mode), not including the editing symbols. NUMVAL and NUMVAL-C return long (64-bit) floating-point values in compatibility mode, and return extended-precision (128-bit) floating-point values in extended mode. A reference to either of these functions represents a reference to a numeric data item. At most 15 decimal digits can be converted accurately to long-precision floating point (as described in the related reference below about conversions and precision). If the argument to NUMVAL or NUMVAL-C has more than 15 digits, it is recommended that you specify the ARITH(EXTEND) compiler option so that an extended-precision function result that can accurately represent the value of the argument is returned. When you use NUMVAL or NUMVAL-C, you do not need to statically declare numeric data in a fixed format nor input data in a precise manner. For example, suppose you define numbers to be entered as follows:
01 X Pic S999V99 leading sign is separate. . . . Accept X from Console

The user of the application must enter the numbers exactly as defined by the PICTURE clause. For example:
+001.23 -300.00

However, using the NUMVAL function, you could code:


01 A Pic x(10). 01 B Pic S999V99. . . . Accept A from Console Compute B = Function Numval(A)

The input could then be:


1.23 -300
RELATED CONCEPTS

Formats for numeric data on page 49 Data format conversions on page 54 Unicode and the encoding of language characters on page 125
RELATED TASKS

Converting to or from national (Unicode) representation on page 134

114

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED REFERENCES

Conversions and precision on page 54 ARITH on page 306

Converting from one code page to another


You can nest the DISPLAY-OF and NATIONAL-OF intrinsic functions to easily convert from any code page to any other code page. For example, the following code converts an EBCDIC string to an ASCII string:
77 EBCDIC-CCSID PIC 9(4) BINARY VALUE 1140. 77 ASCII-CCSID PIC 9(4) BINARY VALUE 819. 77 Input-EBCDIC PIC X(80). 77 ASCII-Output PIC X(80). . . . * Convert EBCDIC to ASCII Move Function Display-of (Function National-of (Input-EBCDIC EBCDIC-CCSID), ASCII-CCSID) to ASCII-output
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125


RELATED TASKS

Converting to or from national (Unicode) representation on page 134

Evaluating data items (intrinsic functions)


You can use intrinsic functions to determine the ordinal position of a character in the collating sequence, to find the largest or smallest item in a series, to find the length of data item, or to determine when a program was compiled. Use these intrinsic functions: v CHAR and ORD to evaluate integers and single alphabetic or alphanumeric characters with respect to the collating sequence used in a program v MAX, MIN, ORD-MAX, and ORD-MIN to find the largest and smallest items in a series of data items, including USAGE NATIONAL data items v LENGTH to find the length of data items, including USAGE NATIONAL data items v WHEN-COMPILED to find the date and time when a program was compiled
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125


RELATED TASKS

Evaluating single characters for collating sequence Finding the largest or smallest data item on page 116 Finding the length of data items on page 118 Finding the date of compilation on page 119

Evaluating single characters for collating sequence


To find out the ordinal position of a given alphabetic or alphanumeric character in the collating sequence, use the ORD function with the character as the argument. ORD returns an integer that represents that ordinal position.
Chapter 6. Handling strings

115

You can use a one-character substring of a data item as the argument to ORD:
IF Function Ord(Customer-record(1:1)) IS > 194 THEN . . .

If you know the ordinal position in the collating sequence of a character, and want to find the character that it corresponds to, use the CHAR function with the integer ordinal position as the argument. CHAR returns the desired character. For example:
INITIALIZE Customer-Name REPLACING ALPHABETIC BY Function Char(65)
RELATED REFERENCES

CHAR (Enterprise COBOL Language Reference) ORD (Enterprise COBOL Language Reference)

Finding the largest or smallest data item


To determine which of two or more alphanumeric, alphabetic, or national data items has the largest value, use the MAX or ORD-MAX intrinsic function. To determine which item has the smallest value, use MIN or ORD-MIN. These functions evaluate according to the collating sequence. To compare numeric items, including those that have USAGE NATIONAL, you can use MAX, ORD-MAX, MIN, or ORD-MIN. With these intrinsic functions, the algebraic values of the arguments are compared. The MAX and MIN functions return the content of one of the arguments that you supply. For example, suppose that your program has the following data definitions:
05 05 05 Arg1 Arg2 Arg3 Pic x(10) Pic x(10) Pic x(10) Value "THOMASSON ". Value "THOMAS ". Value "VALLEJO ".

The following statement assigns VALLEJObbb to the first 10 character positions of Customer-record, where b represents a blank space:
Move Function Max(Arg1 Arg2 Arg3) To Customer-record(1:10)

If you used MIN instead, then THOMASbbbb would be assigned. The functions ORD-MAX and ORD-MIN return an integer that represents the ordinal position (counting from the left) of the argument that has the largest or smallest value in the list of arguments that you supply. If you used the ORD-MAX function in the example above, the compiler would issue an error message because the reference to a numeric function is not in a valid place. The following statement is a valid use of ORD-MAX:
Compute x = Function Ord-max(Arg1 Arg2 Arg3)

The statement above assigns the integer 3 to x if the same arguments are used as in the previous example. If you used ORD-MIN instead, the integer 2 would be returned. The examples above might be more realistic if Arg1, Arg2, and Arg3 were successive elements of an array (table). If you specify a national item for any argument, you must specify all arguments as class national.
RELATED TASKS

Performing arithmetic on page 57

116

Enterprise COBOL for z/OS V4.2 Programming Guide

Processing table items using intrinsic functions on page 86 Returning variable-length results with alphanumeric or national functions
RELATED REFERENCES

MAX (Enterprise COBOL Language Reference) MIN (Enterprise COBOL Language Reference) ORD-MAX (Enterprise COBOL Language Reference) ORD-MIN (Enterprise COBOL Language Reference)

Returning variable-length results with alphanumeric or national functions


The results of alphanumeric or national functions could be of varying lengths and values depending on the function arguments. In the following example, the amount of data moved to R3 and the results of the COMPUTE statement depend on the values and sizes of R1 and R2:
01 01 01 01 . . R1 Pic x(10) value "e". R2 Pic x(05) value "f". R3 Pic x(20) value spaces. L Pic 99. . Move Function Max(R1 R2) to R3 Compute L = Function Length(Function Max(R1 R2))

This code has the following results: v R2 is evaluated to be larger than R1. v The string fbbbb is moved to R3, where b represents a blank space. (The unfilled character positions in R3 are padded with spaces.) v L evaluates to the value 5. If R1 contained g instead of e, the code would have the following results: v R1 would evaluate as larger than R2. v The string gbbbbbbbbb would be moved to R3. (The unfilled character positions in R3 would be padded with spaces.) v The value 10 would be assigned to L. If a program uses national data for function arguments, the lengths and values of the function results could likewise vary. For example, the following code is identical to the fragment above, but uses national data instead of alphanumeric data.
01 01 01 01 . . R1 Pic n(10) national value "e". R2 Pic n(05) national value "f". R3 Pic n(20) national value spaces. L Pic 99 national. . Move Function Max(R1 R2) to R3 Compute L = Function Length(Function Max(R1 R2))

This code has the following results, which are similar to the first set of results except that these are for national characters: v R2 is evaluated to be larger than R1. v The string NX"0066 0020 0020 0020 0020" (the equivalent in national characters of fbbbb, where b represents a blank space), shown here in hexadecimal notation with added spaces for readability, is moved to R3. The unfilled character positions in R3 are padded with national spaces.
Chapter 6. Handling strings

117

v L evaluates to the value 5, the length in national character positions of R2. You might be dealing with variable-length output from alphanumeric or national functions. Plan your program accordingly. For example, you might need to think about using variable-length files when the records that you are writing could be of different lengths:
File Section. FD Output-File Recording Mode V. 01 Short-Customer-Record Pic X(50). 01 Long-Customer-Record Pic X(70). Working-Storage Section. 01 R1 Pic x(50). 01 R2 Pic x(70). . . . If R1 > R2 Write Short-Customer-Record from R1 Else Write Long-Customer-Record from R2 End-if
RELATED TASKS

Finding the largest or smallest data item on page 116 Performing arithmetic on page 57
RELATED REFERENCES

MAX (Enterprise COBOL Language Reference)

Finding the length of data items


You can use the LENGTH function in many contexts (including tables and numeric data) to determine the length of an item. For example, you can use the LENGTH function to determine the length of an alphanumeric or national literal, or a data item of any type except DBCS. The LENGTH function returns the length of a national item (a literal, or any item that has USAGE NATIONAL, including national group items) as an integer equal to the length of the argument in national character positions. It returns the length of any other data item as an integer equal to the length of the argument in alphanumeric character positions. The following COBOL statement demonstrates moving a data item into the field in a record that holds customer names:
Move Customer-name To Customer-record(1:Function Length(Customer-name))

You can also use the LENGTH OF special register, which returns the length in bytes even for national data. Coding either Function Length(Customer-name) or LENGTH OF Customer-name returns the same result for alphanumeric items: the length of Customer-name in bytes. You can use the LENGTH function only where arithmetic expressions are allowed. However, you can use the LENGTH OF special register in a greater variety of contexts. For example, you can use the LENGTH OF special register as an argument to an intrinsic function that accepts integer arguments. (You cannot use an intrinsic function as an operand to the LENGTH OF special register.) You can also use the LENGTH OF special register as a parameter in a CALL statement.

118

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED TASKS

Performing arithmetic on page 57 Creating variable-length tables (DEPENDING ON) on page 81 Processing table items using intrinsic functions on page 86
RELATED REFERENCES

LENGTH (Enterprise COBOL Language Reference) LENGTH OF (Enterprise COBOL Language Reference)

Finding the date of compilation


You can use the WHEN-COMPILED intrinsic function to determine when a program was compiled. The 21-character result indicates the four-digit year, month, day, and time (in hours, minutes, seconds, and hundredths of seconds) of compilation, and the difference in hours and minutes from Greenwich mean time. The first 16 positions are in the following format:
YYYYMMDDhhmmsshh

You can instead use the WHEN-COMPILED special register to determine the date and time of compilation in the following format:
MM/DD/YYhh.mm.ss

The WHEN-COMPILED special register supports only a two-digit year, and carries the time out only to seconds. You can use this special register only as the sending field in a MOVE statement.
RELATED REFERENCES

WHEN-COMPILED (Enterprise COBOL Language Reference)

Chapter 6. Handling strings

119

120

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 7. Processing data in an international environment


Enterprise COBOL supports Unicode UTF-16 as national character data at run time. UTF-16 provides a consistent and efficient way to encode plain text. Using UTF-16, you can develop software that will work with various national languages. Use these COBOL facilities to code and compile programs that process national data: v Data types and literals: Character data types, defined with the USAGE NATIONAL clause and a PICTURE clause that defines data of category national, national-edited, or numeric-edited Numeric data types, defined with the USAGE NATIONAL clause and a PICTURE clause that defines a numeric data item (a national decimal item) or an external floating-point data item (a national floating-point item) National literals, specified with literal prefix N or NX Figurative constant ALL national-literal Figurative constants QUOTE, SPACE, HIGH-VALUE, LOW-VALUE, or ZERO, which have national character (UTF-16) values when used in national-character contexts v The COBOL statements shown in the related reference below about COBOL statements and national data v Intrinsic functions: NATIONAL-OF to convert an alphanumeric or double-byte character set (DBCS) character string to USAGE NATIONAL (UTF-16) DISPLAY-OF to convert a national character string to USAGE DISPLAY in a selected code page (EBCDIC, ASCII, EUC, or UTF-8) The other intrinsic functions shown in the related reference below about intrinsic functions and national data v The GROUP-USAGE NATIONAL clause to define groups that contain only USAGE NATIONAL data items and that behave like elementary category national items in most operations v Compiler options: CODEPAGE to specify the code page to use for alphanumeric and DBCS data in your program NSYMBOL to control whether national or DBCS processing is used for the N symbol in literals and PICTURE clauses You can also take advantage of implicit conversions of alphanumeric or DBCS data items to national representation. The compiler performs such conversions (in most cases) when you move these items to national data items, or compare these items with national data items.
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125 National groups on page 129
RELATED TASKS

Using national data (Unicode) in COBOL on page 126 Converting to or from national (Unicode) representation on page 134
Copyright IBM Corp. 1991, 2009

121

Processing UTF-8 data on page 137 Processing Chinese GB 18030 data on page 138 Comparing national (UTF-16) data on page 139 Coding for use of DBCS support on page 141 Appendix C, Converting double-byte character set (DBCS) data, on page 703
RELATED REFERENCES

COBOL statements and national data Intrinsic functions and national data on page 124 CODEPAGE on page 310 NSYMBOL on page 331 Classes and categories of data (Enterprise COBOL Language Reference) Data categories and PICTURE rules (Enterprise COBOL Language Reference) MOVE statement (Enterprise COBOL Language Reference) General relation conditions (Enterprise COBOL Language Reference)

COBOL statements and national data


You can use national data with the PROCEDURE DIVISION and compiler-directing statements shown in the table below.
Table 15. COBOL statements and national data COBOL statement ACCEPT Can be national identifier-1, identifier-2 Comment identifier-1 is converted from the native code page specified in the CODEPAGE compiler option only if input is from CONSOLE. For more information Assigning input from a screen or file (ACCEPT) on page 37

ADD

All identifiers can be numeric items that have USAGE NATIONAL. identifier-3 (GIVING) can be numeric-edited with USAGE NATIONAL. identifier-2, identifier-3, identifier-4, identifier-5; literal-2, literal-3 identifier-1 can be numeric or numeric-edited with USAGE NATIONAL. arithmetic-expression can contain numeric items that have USAGE NATIONAL. operand-1, operand-2 of the REPLACING phrase identifier-1

Using COMPUTE and other arithmetic statements on page 58

CALL

Passing data on page 465

COMPUTE

Using COMPUTE and other arithmetic statements on page 58

COPY . . . REPLACING DISPLAY

Chapter 18, Compiler-directing statements, on page 363 Displaying values on a screen or in a identifier-1 is converted to EBCDIC only if the CONSOLE file (DISPLAY) on page 38 mnemonic-name is specified directly or indirectly.

122

Enterprise COBOL for z/OS V4.2 Programming Guide

Table 15. COBOL statements and national data (continued) COBOL statement DIVIDE Can be national All identifiers can be numeric items that have USAGE NATIONAL. identifier-3 (GIVING) and identifier-4 (REMAINDER) can be numeric-edited with USAGE NATIONAL. identifier-1; identifier-2 or literal-1 of the REPLACING phrase Comment For more information Using COMPUTE and other arithmetic statements on page 58

INITIALIZE

Examples: initializing data items on If you specify REPLACING NATIONAL or REPLACING page 30 NATIONAL-EDITED, identifier-2 or literal-1 must be valid as a sending operand in a move to identifier-1. If any of these (other than identifier-2, the TALLYING identifier) have USAGE NATIONAL, all must be national. Tallying and replacing data items (INSPECT) on page 111

INSPECT

All identifiers and literals. (identifier-2, the TALLYING integer data item, can have USAGE NATIONAL.) Method-name as identifier-2 or literal-1; identifier-3 or literal-2 in the BY VALUE phrase Merge keys Both the sender and receiver, or only the receiver

INVOKE

Invoking methods (INVOKE) on page 582

MERGE MOVE

The COLLATING SEQUENCE phrase does not apply. Implicit conversions are performed for valid MOVE operands.

Setting sort or merge criteria on page 221 Assigning values to elementary data items (MOVE) on page 34 Assigning values to group data items (MOVE) on page 35 Using COMPUTE and other arithmetic statements on page 58

MULTIPLY

All identifiers can be numeric items that have USAGE NATIONAL. identifier-3 (GIVING) can be numeric-edited with USAGE NATIONAL. Both the key data item and its object of comparison The key data item and its object of comparison must be compatible according to the rules of comparison. If the object of comparison is of class national, the key must be also. The COLLATING SEQUENCE phrase does not apply. If identifier-3, the receiving data item, is national, all identifiers and literals (other than identifier-4, the POINTER identifier) must be national.

SEARCH ALL (binary search)

Doing a binary search (SEARCH ALL) on page 85

SORT STRING

Sort keys All identifiers and literals. (identifier-4, the POINTER integer data item, can have USAGE NATIONAL.)

Setting sort or merge criteria on page 221 Joining data items (STRING) on page 101

Chapter 7. Processing data in an international environment

123

Table 15. COBOL statements and national data (continued) COBOL statement SUBTRACT Can be national All identifiers can be numeric items that have USAGE NATIONAL. identifier-3 (GIVING) can be numeric-edited with USAGE NATIONAL. All identifiers and literals. (identifier-6 and identifier-7, the COUNT and TALLYING integer data items, respectively, can have USAGE NATIONAL.) identifier-1 (the generated XML document); identifier-2 (the source field or fields); identifier-4 or literal-4 (the namespace identifier); identifier-5 or literal-5 (the namespace prefix) identifier-1 (the XML document) If identifier-4, a receiving data item, has USAGE NATIONAL, the sending data item and each delimiter must have USAGE NATIONAL, and each literal must be national. Comment For more information Using COMPUTE and other arithmetic statements on page 58

UNSTRING

Splitting data items (UNSTRING) on page 103

XML GENERATE

Chapter 29, Producing XML output, on page 543

XML PARSE

Chapter 28, Processing XML input, The XML-NTEXT special on page 503 register contains national character document fragments during parsing. XML-NNAMESPACE and XML-NNAMESPACE-PREFIX special registers contain the associated namespace identifier and namespace prefix, if any, in national characters.

RELATED TASKS

Defining numeric data on page 45 Displaying numeric data on page 47 Using national data (Unicode) in COBOL on page 126 Comparing national (UTF-16) data on page 139
RELATED REFERENCES

CODEPAGE on page 310 Classes and categories of data (Enterprise COBOL Language Reference)

Intrinsic functions and national data


You can use arguments of class national with the intrinsic functions shown in the table below.
Table 16. Intrinsic functions and national character data Intrinsic function DISPLAY-OF Function type Alphanumeric For more information Converting national to alphanumeric (DISPLAY-OF) on page 136

124

Enterprise COBOL for z/OS V4.2 Programming Guide

Table 16. Intrinsic functions and national character data (continued) Intrinsic function LENGTH LOWER-CASE, UPPER-CASE NUMVAL, NUMVAL-C MAX, MIN ORD-MAX, ORD-MIN REVERSE Function type Integer National Numeric National Integer National For more information Finding the length of data items on page 118 Converting to uppercase or lowercase (UPPER-CASE, LOWER-CASE) on page 113 Converting to numbers (NUMVAL, NUMVAL-C) on page 113 Finding the largest or smallest data item on page 116 Finding the largest or smallest data item on page 116 Transforming to reverse order (REVERSE) on page 113

You can use national decimal arguments wherever zoned decimal arguments are allowed. You can use national floating-point arguments wherever display floating-point arguments are allowed. (See the related reference below about arguments for a complete list of intrinsic functions that can take integer or numeric arguments.)
RELATED TASKS

Defining numeric data on page 45 Using national data (Unicode) in COBOL on page 126
RELATED REFERENCES

Arguments (Enterprise COBOL Language Reference) Classes and categories of data (Enterprise COBOL Language Reference)

Unicode and the encoding of language characters


Enterprise COBOL provides basic runtime support for Unicode, which can handle tens of thousands of characters that cover all commonly used characters and symbols in the world. A character set is a defined set of characters, but is not associated with a coded representation. A coded character set (also referred to in this documentation as a code page) is a set of unambiguous rules that relate the characters of the set to their coded representation. Each code page has a name and is like a table that sets up the symbols for representing a character set; each symbol is associated with a unique bit pattern, or code point. Each code page also has a coded character set identifier (CCSID), which is a value from 1 to 65,536. Unicode has several encoding schemes, called Unicode Transformation Format (UTF), such as UTF-8, UTF-16, and UTF-32. Enterprise COBOL uses UTF-16 (CCSID 1200) in big-endian format as the representation for national literals and data items that have USAGE NATIONAL. UTF-8 represents ASCII invariant characters a-z, A-Z, 0-9, and certain special characters such as @ , . + - = / * ( ) the same way that they are represented in ASCII. UTF-16 represents these characters as NX'00nn', where X'nn' is the representation of the character in ASCII. For example, the string 'ABC' is represented in UTF-16 as NX'004100420043'. In UTF-8, 'ABC' is represented as X'414243'.

Chapter 7. Processing data in an international environment

125

One or more encoding units are used to represent a character from a coded character set. For UTF-16, an encoding unit takes 2 bytes of storage. Any character defined in any EBCDIC, ASCII, or EUC code page is represented in one UTF-16 encoding unit when the character is converted to the national data representation. Cross-platform considerations: Enterprise COBOL and COBOL for AIX support UTF-16 in big-endian format in national data. COBOL for Windows supports UTF-16 in little-endian format (UTF-16LE) in national data. If you are porting Unicode data that is encoded in UTF-16LE representation to Enterprise COBOL from another platform, you must convert that data to UTF-16 in big-endian format to process the data as national data.
RELATED TASKS

Converting to or from national (Unicode) representation on page 134


RELATED REFERENCES

Storage of character data on page 133 Character sets and code pages (Enterprise COBOL Language Reference)

Using national data (Unicode) in COBOL


In Enterprise COBOL, you can specify national (UTF-16) data in any of several ways. These types of national data are available: v v v v National data items (categories national, national-edited, and numeric-edited) National literals Figurative constants as national characters Numeric data items (national decimal and national floating-point)

In addition, you can define national groups that contain only data items that explicitly or implicitly have USAGE NATIONAL, and that behave in the same way as elementary category national data items in most operations. These declarations affect the amount of storage that is needed.
RELATED CONCEPTS

Unicode and the encoding of language characters on page 125 National groups on page 129
RELATED TASKS

Defining national data items on page 127 Using national literals on page 127 Using national-character figurative constants on page 128 Defining national numeric data items on page 129 Using national groups on page 130 Converting to or from national (Unicode) representation on page 134 Comparing national (UTF-16) data on page 139
RELATED REFERENCES

Storage of character data on page 133 Classes and categories of data (Enterprise COBOL Language Reference)

126

Enterprise COBOL for z/OS V4.2 Programming Guide

Defining national data items


Define national data items with the USAGE NATIONAL clause to hold national (UTF-16) character strings. You can define national data items of the following categories: v National v National-edited v Numeric-edited To define a category national data item, code a PICTURE clause that contains only one or more PICTURE symbols N. To define a national-edited data item, code a PICTURE clause that contains at least one of each of the following symbols: v Symbol N v Simple insertion editing symbol B, 0, or / To define a numeric-edited data item of class national, code a PICTURE clause that defines a numeric-edited item (for example, -$999.99) and code a USAGE NATIONAL clause. You can use a numeric-edited data item that has USAGE NATIONAL in the same way that you use a numeric-edited item that has USAGE DISPLAY. You can also define a data item as numeric-edited by coding the BLANK WHEN ZERO clause for an elementary item that is defined as numeric by its PICTURE clause. If you code a PICTURE clause but do not code a USAGE clause for data items that contain only one or more PICTURE symbols N, you can use the compiler option NSYMBOL(NATIONAL) to ensure that such items are treated as national data items instead of as DBCS items.
RELATED TASKS

Displaying numeric data on page 47


RELATED REFERENCES

NSYMBOL on page 331 BLANK WHEN ZERO clause (Enterprise COBOL Language Reference)

Using national literals


To specify national literals, use the prefix character N and compile with the option NSYMBOL(NATIONAL). You can use either of these notations: v N"character-data" v N'character-data' If you compile with the option NSYMBOL(DBCS), the literal prefix character N specifies a DBCS literal, not a national literal. To specify a national literal as a hexadecimal value, use the prefix NX. You can use either of these notations: v NX"hexadecimal-digits"
Chapter 7. Processing data in an international environment

127

v NX'hexadecimal-digits' Each of the following MOVE statements sets the national data item Y to the UTF-16 value of the characters AB:
01 Y pic . . . Move Move Move NN usage national. NX"00410042" to Y N"AB" to Y "AB" to Y

Do not use alphanumeric hexadecimal literals in contexts that call for national literals, because such usage is easily misunderstood. For example, the following statement also results in moving the UTF-16 characters AB (not the hexadecimal bit pattern C1C2) to Y, where Y is defined as USAGE NATIONAL:
Move X"C1C2" to Y

You cannot use national literals in the SPECIAL-NAMES paragraph or as program-names. You can use a national literal to name an object-oriented method in the METHOD-ID paragraph or to specify a method-name in an INVOKE statement.
RELATED TASKS

Using literals on page 27


RELATED REFERENCES

NSYMBOL on page 331 National literals (Enterprise COBOL Language Reference)

Using national-character figurative constants


You can use the figurative constant ALL national-literal in a context that requires national characters. ALL national-literal represents all or part of the string that is generated by successive concatenations of the encoding units that make up the national literal. You can use the figurative constants QUOTE, SPACE, HIGH-VALUE, LOW-VALUE, or ZERO in a context that requires national characters, such as a MOVE statement, an implicit move, or a relation condition that has national operands. In these contexts, the figurative constant represents a national-character (UTF-16) value. When you use the figurative constant HIGH-VALUE in a context that requires national characters, its value is NX'FFFF'. When you use LOW-VALUE in a context that requires national characters, its value is NX'0000'. Restrictions: You must not use HIGH-VALUE or the value assigned from HIGH-VALUE in a way that results in conversion of the value from one data representation to another (for example, between USAGE DISPLAY and USAGE NATIONAL). X'FF' (the value of HIGH-VALUE in an alphanumeric context when the EBCDIC collating sequence is being used) does not represent a valid EBCDIC character, and NX'FFFF' does not represent a valid national character. Conversion of such a value to another representation results in a substitution character being used (not X'FF' or NX'FFFF'). Consider the following example:
01 natl-data PIC NN Usage National. 01 alph-data PIC XX. . . . MOVE HIGH-VALUE TO natl-data, alph-data IF natl-data = alph-data. . .

128

Enterprise COBOL for z/OS V4.2 Programming Guide

The IF statement above evaluates as false even though each of its operands was set to HIGH-VALUE. Before an elementary alphanumeric operand is compared to a national operand, the alphanumeric operand is treated as though it were moved to a temporary national data item, and the alphanumeric characters are converted to the corresponding national characters. When X'FF' is converted to UTF-16, however, the UTF-16 item gets a substitution character value and so does not compare equally to NX'FFFF'.
RELATED TASKS

Converting to or from national (Unicode) representation on page 134 Comparing national (UTF-16) data on page 139
RELATED REFERENCES

Figurative constants (Enterprise COBOL Language Reference) DISPLAY-OF (Enterprise COBOL Language Reference) Support for Unicode: Using Unicode Services

Defining national numeric data items


Define data items with the USAGE NATIONAL clause to hold numeric data that is represented in national characters (UTF-16). You can define national decimal items and national floating-point items. To define a national decimal item, code a PICTURE clause that contains only the symbols 9, P, S, and V. If the PICTURE clause contains S, the SIGN IS SEPARATE clause must be in effect for that item. To define a national floating-point item, code a PICTURE clause that defines a floating-point item (for example, +99999.9E-99). You can use national decimal items in the same way that you use zoned decimal items. You can use national floating-point items in the same way that you use display floating-point items.
RELATED TASKS

Defining numeric data on page 45 Displaying numeric data on page 47


RELATED REFERENCES

SIGN clause (Enterprise COBOL Language Reference)

National groups
National groups, which are specified either explicitly or implicitly with the GROUP-USAGE NATIONAL clause, contain only data items that have USAGE NATIONAL. In most cases, a national group item is processed as though it were redefined as an elementary category national item described as PIC N(m), where m is the number of national (UTF-16) characters in the group. For some operations on national groups, however (just as for some operations on alphanumeric groups), group semantics apply. Such operations (for example, MOVE CORRESPONDING and INITIALIZE) recognize or process the elementary items within the national group.

Chapter 7. Processing data in an international environment

129

Where possible, use national groups instead of alphanumeric groups that contain USAGE NATIONAL items. National groups provide several advantages for the processing of national data compared to the processing of national data within alphanumeric groups: v When you move a national group to a longer data item that has USAGE NATIONAL, the receiving item is padded with national characters. By contrast, if you move an alphanumeric group that contains national characters to a longer alphanumeric group that contains national characters, alphanumeric spaces are used for padding. As a result, mishandling of data items could occur. v When you move a national group to a shorter data item that has USAGE NATIONAL, the national group is truncated at national-character boundaries. By contrast, if you move an alphanumeric group that contains national characters to a shorter alphanumeric group that contains national characters, truncation might occur between the 2 bytes of a national character. v When you move a national group to a national-edited or numeric-edited item, the content of the group is edited. By contrast, if you move an alphanumeric group to an edited item, no editing takes place. v When you use a national group as an operand in a STRING, UNSTRING, or INSPECT statement: The group content is processed as national characters rather than as single-byte characters. TALLYING and POINTER operands operate at the logical level of national characters. The national group operand is supported with a mixture of other national operand types. By contrast, if you use an alphanumeric group that contains national characters in these contexts, the characters are processed byte by byte. As a result, invalid handling or corruption of data could occur. USAGE NATIONAL groups: A group item can specify the USAGE NATIONAL clause at the group level as a convenient shorthand for the USAGE of each of the elementary data items within the group. Such a group is not a national group, however, but an alphanumeric group, and behaves in many operations, such as moves and compares, like an elementary data item of USAGE DISPLAY (except that no editing or conversion of data occurs).
RELATED TASKS

Assigning values to group data items (MOVE) on page 35 Joining data items (STRING) on page 101 Splitting data items (UNSTRING) on page 103 Tallying and replacing data items (INSPECT) on page 111 Using national groups
RELATED REFERENCES

GROUP-USAGE clause (Enterprise COBOL Language Reference)

Using national groups


To define a group data item as a national group, code a GROUP-USAGE NATIONAL clause at the group level for the item. The group can contain only data items that explicitly or implicitly have USAGE NATIONAL. The following data description entry specifies that a level-01 group and its subordinate groups are national group items:

130

Enterprise COBOL for z/OS V4.2 Programming Guide

01

Nat-Group-1 GROUP-USAGE NATIONAL. 02 Group-1. 04 Month PIC 99. 04 DayOf PIC 99. 04 Year PIC 9999. 02 Group-2 GROUP-USAGE NATIONAL. 04 Amount PIC 9(4).99 USAGE NATIONAL.

In the example above, Nat-Group-1 is a national group, and its subordinate groups Group-1 and Group-2 are also national groups. A GROUP-USAGE NATIONAL clause is implied for Group-1, and USAGE NATIONAL is implied for the subordinate items in Group-1. Month, DayOf, and Year are national decimal items, and Amount is a numeric-edited item that has USAGE NATIONAL. You can subordinate national groups within alphanumeric groups as in the following example:
01 Alpha-Group-1. 02 Group-1. 04 Month PIC 99. 04 DayOf PIC 99. 04 Year PIC 9999. 02 Group-2 GROUP-USAGE NATIONAL. 04 Amount PIC 9(4).99.

In the example above, Alpha-Group-1 and Group-1 are alphanumeric groups; USAGE DISPLAY is implied for the subordinate items in Group-1. (If Alpha-Group-1 specified USAGE NATIONAL at the group level, USAGE NATIONAL would be implied for each of the subordinate items in Group-1. However, Alpha-Group-1 and Group-1 would be alphanumeric groups, not national groups, and would behave like alphanumeric groups during operations such as moves and compares.) Group-2 is a national group, and USAGE NATIONAL is implied for the numeric-edited item Amount. You cannot subordinate alphanumeric groups within national groups. All elementary items within a national group must be explicitly or implicitly described as USAGE NATIONAL, and all group items within a national group must be explicitly or implicitly described as GROUP-USAGE NATIONAL.
RELATED CONCEPTS

National groups on page 129


RELATED TASKS

Using national groups as elementary items Using national groups as group items on page 132
RELATED REFERENCES

GROUP-USAGE clause (Enterprise COBOL Language Reference)

Using national groups as elementary items


In most cases, you can use a national group as though it were an elementary data item. In the following example, a national group item, Group-1, is moved to a national-edited item, Edited-date. Because Group-1 is treated as an elementary data item during the move, editing takes place in the receiving data item. The value in Edited-date after the move is 06/23/2009 in national characters.

Chapter 7. Processing data in an international environment

131

01 01

Edited-date PIC NN/NN/NNNN USAGE NATIONAL. Group-1 GROUP-USAGE NATIONAL. 02 Month PIC 99 VALUE 06. 02 DayOf PIC 99 VALUE 23. 02 Year PIC 9999 VALUE 2009. . . . MOVE Group-1 to Edited-date.

If Group-1 were instead an alphanumeric group in which each of its subordinate items had USAGE NATIONAL (specified either explicitly with a USAGE NATIONAL clause on each elementary item, or implicitly with a USAGE NATIONAL clause at the group level), a group move, rather than an elementary move, would occur. Neither editing nor conversion would take place during the move. The value in the first eight character positions of Edited-date after the move would be 06232009 in national characters, and the value in the remaining two character positions would be 4 bytes of alphanumeric spaces.
RELATED TASKS

Assigning values to group data items (MOVE) on page 35 Comparing national data and alphanumeric-group operands on page 141 Using national groups as group items
RELATED REFERENCES

MOVE statement (Enterprise COBOL Language Reference)

Using national groups as group items


In some cases when you use a national group, it is handled with group semantics; that is, the elementary items in the group are recognized or processed. In the following example, an INITIALIZE statement that acts upon national group item Group-OneN causes the value 15 in national characters to be moved to only the numeric items in the group:
01 Group-OneN Group-Usage National. 05 Trans-codeN Pic N Value "A". 05 Part-numberN Pic NN Value "XX". 05 Trans-quanN Pic 99 Value 10. . . . Initialize Group-OneN Replacing Numeric Data By 15

Because only Trans-quanN in Group-OneN above is numeric, only Trans-quanN receives the value 15. The other subordinate items are unchanged. The table below summarizes the cases where national groups are processed with group semantics.
Table 17. National group items that are processed with group semantics Language feature Uses of national group items Comment Elementary items within the national group are processed like elementary items that have USAGE NATIONAL within an alphanumeric group. The national group item is in effect shorthand for the set of host variables that are subordinate to the group item.

CORRESPONDING phrase Specify a national group item for of the ADD, SUBTRACT, processing as a group in or MOVE statement accordance with the rules of the CORRESPONDING phrase. Host variable in EXEC SQL statement Specify a national group item as a host variable.

132

Enterprise COBOL for z/OS V4.2 Programming Guide

Table 17. National group items that are processed with group semantics (continued) Language feature INITIALIZE statement Uses of national group items Specify a national group for processing as a group in accordance with the rules of the INITIALIZE statement. Use the name of a national group item to qualify the names of elementary data items and of subordinate group items in the national group. Comment Elementary items within the national group are initialized like elementary items that have USAGE NATIONAL within an alphanumeric group. Follow the same rules for qualification as for an alphanumeric group.

Name qualification

THROUGH phrase of the To specify a national group item in The result is an alphanumeric RENAMES clause the THROUGH phrase, use the same group item. rules as for an alphanumeric group item. FROM phrase of the XML GENERATE statement Specify a national group item in the FROM phrase for processing as a group in accordance with the rules of the XML GENERATE statement. Elementary items within the national group are processed like elementary items that have USAGE NATIONAL within an alphanumeric group.

RELATED TASKS

Initializing a structure (INITIALIZE) on page 32 Initializing a table (INITIALIZE) on page 76 Assigning values to elementary data items (MOVE) on page 34 Assigning values to group data items (MOVE) on page 35 Finding the length of data items on page 118 Generating XML output on page 543 Using national group items in SQL statements on page 422
RELATED REFERENCES

Qualification (Enterprise COBOL Language Reference) RENAMES clause (Enterprise COBOL Language Reference)

Storage of character data


Use the table below to compare alphanumeric (DISPLAY), DBCS (DISPLAY-1), and Unicode (NATIONAL) encoding and to plan storage usage.
Table 18. Encoding and size of alphanumeric, DBCS, and national data Characteristic Character encoding unit Code page Encoding units per graphic character Bytes per graphic character DISPLAY 1 byte EBCDIC 1 1 byte DISPLAY-1 2 bytes EBCDIC DBCS 1 2 bytes NATIONAL 2 bytes UTF-16BE1 1 or 22 2 or 4 bytes

Chapter 7. Processing data in an international environment

133

Table 18. Encoding and size of alphanumeric, DBCS, and national data (continued) Characteristic DISPLAY DISPLAY-1 NATIONAL

1. Use the CODEPAGE compiler option to specify the EBCDIC code page that is applicable to alphanumeric or DBCS data. 2. Most characters are represented in UTF-16 using one encoding unit. In particular, the following characters are represented using a single UTF-16 encoding unit per character: v COBOL characters A-Z, a-z, 0-9, space, + - * / = $ , ; . ( ) > < : v All characters that are converted from an EBCDIC or ASCII code page

RELATED CONCEPTS

Unicode and the encoding of language characters on page 125

Converting to or from national (Unicode) representation


You can implicitly or explicitly convert data items to national (UTF-16) representation. You can implicitly convert alphabetic, alphanumeric, DBCS, or integer data to national data by using the MOVE statement. Implicit conversions also take place in other COBOL statements, such as IF statements that compare an alphanumeric data item with a data item that has USAGE NATIONAL. You can explicitly convert to and from national data items by using the intrinsic functions NATIONAL-OF and DISPLAY-OF, respectively. By using these intrinsic functions, you can specify a code page for the conversion that is different from the code page that is in effect with the CODEPAGE compiler option.
RELATED TASKS

Converting alphanumeric, DBCS, and integer to national (MOVE) Converting alphanumeric or DBCS to national (NATIONAL-OF) on page 135 Converting national to alphanumeric (DISPLAY-OF) on page 136 Overriding the default code page on page 136 Comparing national (UTF-16) data on page 139
RELATED REFERENCES

CODEPAGE on page 310 Conversion exceptions on page 136

Converting alphanumeric, DBCS, and integer to national (MOVE)


You can use a MOVE statement to implicitly convert data to national representation. You can move the following kinds of data to category national or national-edited data items, and thus convert the data to national representation: v v v v v v Alphabetic Alphanumeric Alphanumeric-edited DBCS Integer of USAGE DISPLAY Numeric-edited of USAGE DISPLAY

134

Enterprise COBOL for z/OS V4.2 Programming Guide

You can likewise move the following kinds of data to numeric-edited data items that have USAGE NATIONAL: v Alphanumeric v Display floating-point (floating-point of USAGE DISPLAY) v Numeric-edited of USAGE DISPLAY v Integer of USAGE DISPLAY For complete rules about moves to national data, see the related reference about the MOVE statement. For example, the MOVE statement below moves the alphanumeric literal "AB" to the national data item UTF16-Data:
01 UTF16-Data Pic N(2) Usage National. . . . Move "AB" to UTF16-Data

After the MOVE statement above, UTF16-Data contains NX'00410042', the national representation of the alphanumeric characters AB. If padding is required in a receiving data item that has USAGE NATIONAL, the default UTF-16 space character (NX'0020') is used. If truncation is required, it occurs at the boundary of a national-character position.
RELATED TASKS

Assigning values to elementary data items (MOVE) on page 34 Assigning values to group data items (MOVE) on page 35 Displaying numeric data on page 47 Coding for use of DBCS support on page 141
RELATED REFERENCES

MOVE statement (Enterprise COBOL Language Reference)

Converting alphanumeric or DBCS to national (NATIONAL-OF)


Use the NATIONAL-OF intrinsic function to convert alphabetic, alphanumeric, or DBCS data to a national data item. Specify the source code page as the second argument if the source is encoded in a different code page than is in effect with the CODEPAGE compiler option. Example: converting to and from national data on page 137
RELATED TASKS

Processing UTF-8 data on page 137 Processing Chinese GB 18030 data on page 138 Processing alphanumeric data items that contain DBCS data on page 143
RELATED REFERENCES

CODEPAGE on page 310 NATIONAL-OF (Enterprise COBOL Language Reference)

Chapter 7. Processing data in an international environment

135

Converting national to alphanumeric (DISPLAY-OF)


Use the DISPLAY-OF intrinsic function to convert national data to an alphanumeric (USAGE DISPLAY) character string that is represented in a code page that you specify as the second argument. If you omit the second argument, the output code page is the one that was in effect with the CODEPAGE compiler option when the source was compiled. If you specify an EBCDIC or ASCII code page that combines single-byte character set (SBCS) and DBCS characters, the returned string might contain a mixture of SBCS and DBCS characters. The DBCS substrings are delimited by shift-in and shift-out characters if the code page in effect for the function is an EBCDIC code page. Example: converting to and from national data on page 137
RELATED TASKS

Processing UTF-8 data on page 137 Processing Chinese GB 18030 data on page 138
RELATED REFERENCES

DISPLAY-OF (Enterprise COBOL Language Reference)

Overriding the default code page


In some cases, you might need to convert data to or from a code page that differs from the CCSID that is specified as the CODEPAGE option value. To do so, convert the item by using a conversion function in which you explicitly specify the code page. If you specify a code page as an argument to the DISPLAY-OF intrinsic function, and the code page differs from the code page that is in effect with the CODEPAGE compiler option, do not use the function result in any operations that involve implicit conversion (such as an assignment to, or comparison with, a national data item). Such operations assume the EBCDIC code page that is specified with the CODEPAGE compiler option.
RELATED REFERENCES

CODEPAGE on page 310

Conversion exceptions
Implicit or explicit conversion between national data and alphanumeric data can fail and generate a severity-3 Language Environment condition. Failure can occur if the code page that you specified implicitly or explicitly is not a valid code page. A character that does not have a counterpart in the target CCSID does not result in a conversion exception. Such a character is converted to a substitution character in the target code page.
RELATED REFERENCES

CODEPAGE on page 310

136

Enterprise COBOL for z/OS V4.2 Programming Guide

Example: converting to and from national data


The following example shows the NATIONAL-OF and DISPLAY-OF intrinsic functions and the MOVE statement for converting to and from national (UTF-16) data items. It also demonstrates the need for explicit conversions when you operate on strings that are encoded in multiple code pages.
CBL CODEPAGE(00037) * . . . 01 Data-in-Unicode pic N(100) usage national. 01 Data-in-Greek pic X(100). 01 other-data-in-US-English pic X(12) value "PRICE in $ =". * . . . Read Greek-file into Data-in-Greek Move function National-of(Data-in-Greek, 00875) to Data-in-Unicode * . . . process Data-in-Unicode here . . . Move function Display-of(Data-in-Unicode, 00875) to Data-in-Greek Write Greek-record from Data-in-Greek

The example above works correctly because the input code page is specified. Data-in-Greek is converted as data represented in CCSID 00875 (Greek). However, the following statement results in an incorrect conversion unless all the characters in the item happen to be among those that have a common representation in both the Greek and the English code pages:
Move Data-in-Greek to Data-in-Unicode

The MOVE statement above converts Data-in-Greek to Unicode representation based on the CCSID 00037 (U.S. English) to UTF-16 conversion. This conversion does not produce the expected results because Data-in-Greek is encoded in CCSID 00875. If you can correctly set the CODEPAGE compiler option to CCSID 00875 (that is, the rest of your program also handles EBCDIC data in Greek), you can code the same example correctly as follows:
CBL CODEPAGE(00875) * . . . 01 Data-in-Unicode pic N(100) usage national. 01 Data-in-Greek pic X(100). * . . . Read Greek-file into Data-in-Greek * . . . process Data-in-Greek here ... * . . . or do the following (if need to process data in Unicode): Move Data-in-Greek to Data-in-Unicode * . . . process Data-in-Unicode Move function Display-of(Data-in-Unicode) to Data-in-Greek Write Greek-record from Data-in-Greek

Processing UTF-8 data


When you need to process UTF-8 data, first convert the UTF-8 data to UTF-16 in a national data item. After processing the national data, convert it back to UTF-8 for output. For the conversions, use the intrinsic functions NATIONAL-OF and DISPLAY-OF, respectively. Use code page 1208 for UTF-8 data. You need to do two steps to convert ASCII or EBCDIC data to UTF-8: 1. Use the function NATIONAL-OF to convert the ASCII or EBCDIC string to a national (UTF-16) string. 2. Use the function DISPLAY-OF to convert the national string to UTF-8.
Chapter 7. Processing data in an international environment

137

The following example converts Greek EBCDIC data to UTF-8:

Usage note: Use care if you use reference modification to refer to data encoded in UTF-8. UTF-8 characters are encoded with a varying number of bytes per character. Avoid operations that might split a multibyte character.
RELATED TASKS

Referring to substrings of data items on page 107 Converting to or from national (Unicode) representation on page 134 Parsing XML documents encoded in UTF-8 on page 525

Processing Chinese GB 18030 data


GB 18030 is a national-character standard specified by the government of the Peoples Republic of China. GB 18030 characters can be encoded in either UTF-16 or in code page CCSID 1392. Code page 1392 is an ASCII multibyte code page that uses 1, 2, or 4 bytes per character. A subset of the GB 18030 characters can be encoded in the Chinese ASCII code page, CCSID 1386, or in the Chinese EBCDIC code page, CCSID 1388. Enterprise COBOL does not have explicit support for GB 18030, but does support the processing of GB 18030 characters in several ways. You can: v Use DBCS data items to process GB 18030 characters that are represented in CCSID 1388. v Use national data items to define and process GB 18030 characters that are represented in UTF-16, CCSID 01200. v Process data in any code page (including CCSID 1388 or 1392) by converting the data to UTF-16, processing the UTF-16 data, and then converting the data back to the original code-page representation. When you need to process Chinese GB 18030 data that requires conversion, first convert the input data to UTF-16 in a national data item. After you process the national data item, convert it back to Chinese GB 18030 for output. For the conversions, use the intrinsic functions NATIONAL-OF and DISPLAY-OF, respectively, and specify code page 1388 or 1392 as the second argument of each function. The following example illustrates these conversions:

RELATED TASKS

Converting to or from national (Unicode) representation on page 134 Coding for use of DBCS support on page 141

138

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED REFERENCES

Storage of character data on page 133

Comparing national (UTF-16) data


You can compare national (UTF-16) data, that is, national literals and data items that have USAGE NATIONAL (whether of class national or class numeric), explicitly or implicitly with other kinds of data in relation conditions. You can code conditional expressions that use national data in the following statements: v EVALUATE v IF v INSPECT v PERFORM v SEARCH v STRING v UNSTRING The following sections provide an overview about comparing national data to other data items. For full details, see the related references.
RELATED TASKS

Comparing Comparing Comparing Comparing Comparing

two class national operands class national and class numeric operands on page 140 national numeric and other numeric operands on page 140 national and other character-string operands on page 140 national data and alphanumeric-group operands on page 141

RELATED REFERENCES

Relation conditions (Enterprise COBOL Language Reference) General relation conditions (Enterprise COBOL Language Reference) National comparisons (Enterprise COBOL Language Reference) Group comparisons (Enterprise COBOL Language Reference)

Comparing two class national operands


You can compare the character values of two operands of class national. Either operand (or both) can be any of the following types of items: v A national group v An elementary category national or national-edited data item v A numeric-edited data item that has USAGE NATIONAL One of the operands can instead be a national literal or a national intrinsic function. When you compare two class national operands that have the same length, they are determined to be equal if all pairs of the corresponding characters are equal. Otherwise, comparison of the binary values of the first pair of unequal characters determines the operand with the larger binary value.

Chapter 7. Processing data in an international environment

139

When you compare operands that have unequal lengths, the shorter operand is treated as if it were padded on the right with default UTF-16 space characters (NX'0020') to the length of the longer operand. The PROGRAM COLLATING SEQUENCE clause does not affect the comparison of two class national operands.
RELATED CONCEPTS

National groups on page 129


RELATED TASKS

Using national groups on page 130


RELATED REFERENCES

National comparisons (Enterprise COBOL Language Reference)

Comparing class national and class numeric operands


You can compare national literals or class national data items to integer literals or numeric data items that are defined as integer (that is, national decimal items or zoned decimal items). At most one of the operands can be a literal. You can also compare national literals or class national data items to floating-point data items (that is, display floating-point or national floating-point items). Numeric operands are converted to national (UTF-16) representation if they are not already in national representation. A comparison is made of the national character values of the operands.
RELATED REFERENCES

General relation conditions (Enterprise COBOL Language Reference)

Comparing national numeric and other numeric operands


National numeric operands (national decimal and national floating-point operands) are data items of class numeric that have USAGE NATIONAL. You can compare the algebraic values of numeric operands regardless of their USAGE. Thus you can compare a national decimal item or a national floating-point item with a binary item, an internal-decimal item, a zoned decimal item, a display floating-point item, or any other numeric item.
RELATED TASKS

Defining national numeric data items on page 129


RELATED REFERENCES

General relation conditions (Enterprise COBOL Language Reference)

Comparing national and other character-string operands


You can compare the character value of a national literal or class national data item with the character value of any of the following other character-string operands: alphabetic, alphanumeric, alphanumeric-edited, DBCS, or numeric-edited of USAGE DISPLAY.

140

Enterprise COBOL for z/OS V4.2 Programming Guide

These operands are treated as if they were moved to an elementary national data item. The characters are converted to national (UTF-16) representation, and the comparison proceeds with two national character operands.
RELATED TASKS

Using national-character figurative constants on page 128


RELATED REFERENCES

National comparisons (Enterprise COBOL Language Reference)

Comparing national data and alphanumeric-group operands


You can compare a national literal, a national group item, or any elementary data item that has USAGE NATIONAL to an alphanumeric group. Neither operand is converted. The national operand is treated as if it were moved to an alphanumeric group item of the same size in bytes as the national operand, and the two groups are compared. An alphanumeric comparison is done regardless of the representation of the subordinate items in the alphanumeric group operand. For example, Group-XN is an alphanumeric group that consists of two subordinate items that have USAGE NATIONAL:
01 Group-XN. 02 TransCode PIC NN Value "AB" Usage National. 02 Quantity PIC 999 Value 123 Usage National. . . . If N"AB123" = Group-XN Then Display "EQUAL" Else Display "NOT EQUAL".

When the IF statement above is executed, the 10 bytes of the national literal N"AB123" are compared byte by byte to the content of Group-XN. The items compare equally, and EQUAL is displayed.
RELATED REFERENCES

Group comparisons (Enterprise COBOL Language Reference)

Coding for use of DBCS support


IBM Enterprise COBOL for z/OS supports using applications in any of many national languages, including languages that use double-byte character sets (DBCS). The following list summarizes the support for DBCS: v DBCS characters in user-defined words (DBCS names) v v v v DBCS characters in comments DBCS data items (defined with PICTURE N, G, or G and B) DBCS literals DBCS compiler option

RELATED TASKS

Declaring DBCS data on page 142 Using DBCS literals on page 142 Testing for valid DBCS characters on page 143

Chapter 7. Processing data in an international environment

141

Processing alphanumeric data items that contain DBCS data on page 143 Appendix C, Converting double-byte character set (DBCS) data, on page 703
RELATED REFERENCES

DBCS on page 317

Declaring DBCS data


Use the PICTURE and USAGE clauses to declare DBCS data items. DBCS data items can use PICTURE symbols G, G and B, or N. Each DBCS character position is 2 bytes in length. You can specify a DBCS data item by using the USAGE DISPLAY-1 clause. When you use PICTURE symbol G, you must specify USAGE DISPLAY-1. When you use PICTURE symbol N but omit the USAGE clause, USAGE DISPLAY-1 or USAGE NATIONAL is implied depending on the setting of the NSYMBOL compiler option. If you use a VALUE clause with the USAGE clause in the declaration of a DBCS item, you must specify a DBCS literal or the figurative constant SPACE or SPACES. For the purpose of handling reference modifications, each character in a DBCS data item is considered to occupy the number of bytes that corresponds to the code-page width (that is, 2).
RELATED REFERENCES

NSYMBOL on page 331

Using DBCS literals


You can use the prefix N or G to represent a DBCS literal. That is, you can specify a DBCS literal in either of these ways: v N'dbcs characters' (provided that the compiler option NSYMBOL(DBCS) is in effect) v G'dbcs characters' You can use quotation marks (") or single quotation marks (') as the delimiters of a DBCS literal irrespective of the setting of the APOST or QUOTE compiler option. You must code the same opening and closing delimiter for a DBCS literal. The shift-out (SO) control character X'0E' must immediately follow the opening delimiter, and the shift-in (SI) control character X'0F' must immediately precede the closing delimiter. In addition to DBCS literals, you can use alphanumeric literals to specify any character in one of the supported code pages. However, any string of DBCS characters that is within an alphanumeric literal must be delimited by the SO and SI characters, and the DBCS compiler option must be in effect for the SO and SI characters to be recognized as shift codes. You cannot continue an alphanumeric literal that contains DBCS characters. The length of a DBCS literal is likewise limited by the available space in Area B on a single source line. The maximum length of a DBCS literal is thus 28 double-byte characters.

142

Enterprise COBOL for z/OS V4.2 Programming Guide

An alphanumeric literal that contains DBCS characters is processed byte by byte, that is, with semantics appropriate for single-byte characters, except when it is converted explicitly or implicitly to national data representation, as for example in an assignment to or comparison with a national data item.
RELATED TASKS

Using figurative constants on page 28


RELATED REFERENCES

DBCS on page 317 NSYMBOL on page 331 QUOTE/APOST on page 340 DBCS literals (Enterprise COBOL Language Reference)

Testing for valid DBCS characters


The Kanji class test tests for valid Japanese graphic characters. This testing includes Katakana, Hiragana, Roman, and Kanji character sets. The Kanji class test is done by checking characters for the range X'41' through X'7E' in the first byte and X'41' through X'FE' in the second byte, plus the space character X'4040'. The DBCS class test tests for valid graphic characters for the code page. The DBCS class test is done by checking characters for the range X'41' through X'FE' in both the first and second byte of each character, plus the space character X'4040'.
RELATED TASKS

Coding conditional expressions on page 94


RELATED REFERENCES

Class condition (Enterprise COBOL Language Reference)

Processing alphanumeric data items that contain DBCS data


If you use byte-oriented operations (for example, STRING, UNSTRING, or reference modification) on an alphanumeric data item that contains DBCS characters, results are unpredictable. You should instead convert the item to a national data item before you process it. That is, do these steps: 1. Convert the item to UTF-16 in a national data item by using a MOVE statement or the NATIONAL-OF intrinsic function. 2. Process the national data item as needed. 3. Convert the result back to an alphanumeric data item by using the DISPLAY-OF intrinsic function.
RELATED TASKS

Joining data items (STRING) on page 101 Splitting data items (UNSTRING) on page 103 Referring to substrings of data items on page 107 Converting to or from national (Unicode) representation on page 134
Chapter 7. Processing data in an international environment

143

144

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 8. Processing files


Reading and writing data is an essential part of every program. Your program retrieves information, processes it as you request, and then produces the results. The source of the information and the target for the results can be one or more of the following items: v Another program v Direct-access storage device v Magnetic tape v Printer v Terminal v Card reader or punch The information as it exists on an external device is in a physical record or block, a collection of information that is handled as a unit by the system during input or output operations. Your COBOL program does not directly handle physical records. It processes logical records. A logical record can correspond to a complete physical record, part of a physical record, or to parts or all of one or more physical records. Your COBOL program handles logical records exactly as you have defined them. In COBOL, a collection of logical records is a file, a sequence of pieces of information that your program can process.
RELATED CONCEPTS

File organization and input-output devices


RELATED TASKS

Choosing file organization and access mode on page 147 Allocating files on page 149 Checking for input or output errors on page 150

File organization and input-output devices


Depending on the input-output devices, your file organization can be sequential, line sequential, indexed, or relative. Decide on the file types and devices to be used when you design your program. You have the following choices of file organization: Sequential file organization The chronological order in which records are entered when a file is created establishes the arrangement of the records. Each record except the first has a unique predecessor record, and each record except the last has a unique successor record. Once established, these relationships do not change. The access (record transmission) mode allowed for sequential files is sequential only.

Copyright IBM Corp. 1991, 2009

145

Line-sequential file organization Line-sequential files are sequential files that reside on the hierarchical file system (HFS) and that contain only characters as data. Each record ends with a newline character. The only access (record transmission) mode allowed for line-sequential files is sequential. Indexed file organization Each record in the file contains a special field whose contents form the record key. The position of the key is the same in each record. The index component of the file establishes the logical arrangement of the file, an ordering by record key. The actual physical arrangement of the records in the file is not significant to your COBOL program. An indexed file can also use alternate indexes in addition to the record key. These keys let you access the file using a different logical ordering of the records. The access (record transmission) modes allowed for indexed files are sequential, random, or dynamic. When you read or write indexed files sequentially, the sequence is that of the key values. Relative file organization Records in the file are identified by their location relative to the beginning of the file. The first record in the file has a relative record number of 1, the tenth record has a relative record number of 10, and so on. The access (record transmission) modes allowed for relative files are sequential, random, or dynamic. When relative files are read or written sequentially, the sequence is that of the relative record number. With IBM Enterprise COBOL for z/OS, requests to the operating system for the storage and retrieval of records from input-output devices are handled by the two access methods QSAM and VSAM, and the UNIX file system. The device type upon which you elect to store your data could affect the choices of file organization available to you. Direct-access storage devices provide greater flexibility in the file organization options. Sequential-only devices limit organization options but have other characteristics, such as the portability of tapes, that might be useful. Sequential-only devices Terminals, printers, card readers, and punches are called unit-record devices because they process one line at a time. Therefore, you must also process records one at a time sequentially in your program when it reads from or writes to unit-record devices. On tape, records are ordered sequentially, so your program must process them sequentially. Use QSAM physical sequential files when processing tape files. The records on tape can be fixed length or variable length. Direct-access storage devices Direct-access storage devices hold many records. The record arrangement of files stored on these devices determines the ways that your program can process the data. When using direct-access devices, you have greater flexibility within your program, because your can use several types of file organization: v Sequential (VSAM or QSAM) v Line sequential (UNIX)

146

Enterprise COBOL for z/OS V4.2 Programming Guide

v Indexed (VSAM) v Relative (VSAM)


RELATED TASKS

Allocating files on page 149 Chapter 9, Processing QSAM files, on page 151 Chapter 10, Processing VSAM files, on page 179 Chapter 11, Processing line-sequential files, on page 207 Choosing file organization and access mode

Choosing file organization and access mode


There are several guidelines you can use to determine which file organization and access mode to use in an application. Consider the following guidelines when choosing file organization: v If an application accesses records (whether fixed-length or variable-length) only sequentially and does not insert records between existing records, a QSAM or VSAM sequential file is the simplest type. v If you are developing an application for UNIX that sequentially accesses records that contain only printable characters and certain control characters, line-sequential files work best. v If an application requires both sequential and random access (whether records are fixed length or variable length), a VSAM indexed file is the most flexible type. v If an application inserts and deletes records randomly, a relative file works well. Consider the following guidelines when choosing access mode: v If a large percentage of a file is referenced or updated in an application, sequential access is faster than random or dynamic access. v If a small percentage of records is processed during each run of an application, use random or dynamic access.
Table 19. Summary of file organizations, access modes, and record formats of COBOL files File organization QSAM (physical sequential) Line sequential VSAM sequential (ESDS) VSAM indexed (KSDS) VSAM relative (RRDS) Sequential access X X X X X X X X X Random access Dynamic access Fixed length X X1 X X X Variable length X X X X X

1. The data itself is in variable format but can be read into and written from COBOL fixed-length records.

RELATED REFERENCES

Format for coding input and output on page 148 Allowable control characters on page 208

Chapter 8. Processing files

147

Format for coding input and output


The following code shows the general format of input-output coding. Explanations of the user-supplied information follow the code.
IDENTIFICATION DIVISION. . . . ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT filename ASSIGN TO assignment-name (1) (2) ORGANIZATION IS org ACCESS MODE IS access (3) (4) FILE STATUS IS file-status (5) . . . DATA DIVISION. FILE SECTION. FD filename 01 recordname (6) nn . . . fieldlength & type (7) (8) nn . . . fieldlength & type . . . WORKING-STORAGE SECTION 01 file-status PICTURE 99. . . . PROCEDURE DIVISION. . . . OPEN iomode filename (9) . . . READ filename . . . WRITE recordname . . . CLOSE filename . . . STOP RUN.

The user-supplied information in the code above is as follows: (1) filename Any legal COBOL name. You must use the same file-name in the SELECT clause and in the FD entry, and on the READ, OPEN, and CLOSE statements. In addition, the file-name is required if you use the START or DELETE statements. This name is not necessarily the actual name of the data set as known to the system. Each file requires its own SELECT clause, FD entry, and input-output statements. (2) assignment-name Any name you choose, provided that it follows COBOL and system naming rules. The name can be 1-30 characters long if it is a user-defined word, or 1-160 characters long if it is a literal. You code the name part of the assignment-name on a DD statement, in an ALLOCATE command (TSO) or as an environment variable (for example, in an export command) (UNIX). (3) org The organization can be SEQUENTIAL, LINE SEQUENTIAL, INDEXED, or RELATIVE. This clause is optional for QSAM files. (4) access The access mode can be SEQUENTIAL, RANDOM, or DYNAMIC. For sequential file processing, including line-sequential, you can omit this clause. (5) file-status The COBOL file status key. You can specify the file status key as a

148

Enterprise COBOL for z/OS V4.2 Programming Guide

two-character category alphanumeric or category national item, or as a two-digit zoned decimal (USAGE DISPLAY) or national decimal (USAGE NATIONAL) item. (6) recordname The name of the record used in the WRITE and REWRITE statements. (7) fieldlength The logical length of the field. (8) type The record format of the file. If you break the record entry beyond the level-01 description, each element should map accurately against the fields in the record. (9) iomode The INPUT or OUTPUT mode. If you are only reading from a file, code INPUT. If you are only writing to it, code OUTPUT or EXTEND. If you are both reading and writing, code I-O, except for organization LINE SEQUENTIAL.
RELATED TASKS

Chapter 9, Processing QSAM files, on page 151 Chapter 10, Processing VSAM files, on page 179 Chapter 11, Processing line-sequential files, on page 207

Allocating files
For any type of file (sequential, line sequential, indexed, or relative) in your z/OS or UNIX applications, you can define the external name with either a ddname or an environment-variable name. The external name is the name in the assignment-name of the ASSIGN clause. If the file is in the HFS, you can use either a DD definition or an environment variable to define the file by specifying its path name with the PATH keyword. The environment-variable name must be uppercase. The allowable attributes for its value depend on the organization of the file being defined. Because you can define the external name in either of two ways, the COBOL run time goes through the following steps to find the definition of the file: 1. If the ddname is explicitly allocated, it is used. The definition can be from a DD statement in JCL, an ALLOCATE command from TSO/E, or a user-initiated dynamic allocation. 2. If the ddname is not explicitly allocated and an environment variable of the same name is set, the value of the environment variable is used. The file is dynamically allocated using the attributes specified by the environment variable. At a minimum, you must specify either the PATH() or DSN() option. All options and attributes must be in uppercase, except for the path-name suboption of the PATH option, which is case sensitive. You cannot specify a temporary data-set name in the DSN() option. File status code 98 results from any of the following: v The contents (including a value of null or all blanks) of the environment variable are not valid. v The dynamic allocation of the file fails. v The dynamic deallocation of the file fails.
Chapter 8. Processing files

149

The COBOL run time checks the contents of the environment variable at each OPEN statement. If a file with the same external name was dynamically allocated by a previous OPEN statement, and the contents of the environment variable have changed since that OPEN, the run time dynamically deallocates the previous allocation and reallocates the file using the options currently set in the environment variable. If the contents of the environment variable have not changed, the run time uses the current allocation. 3. If neither a ddname nor an environment variable is defined, the following steps occur: a. If the allocation is for a QSAM file and the CBLQDA runtime option is in effect, CBLQDA dynamic allocation processing takes place for those eligible files. This type of implicit dynamic allocation persists for the life of the run unit and cannot be reallocated. b. Otherwise, the allocation fails. The COBOL run time deallocates all dynamic allocations at run unit termination, except for implicit CBLQDA allocations.
RELATED TASKS

Setting and accessing environment variables on page 438 Defining and allocating QSAM files on page 166 Dynamically creating QSAM files on page 163 Allocating VSAM files on page 200

Checking for input or output errors


After each input or output statement is performed, the file status key is updated with a value that indicates the success or failure of the operation. Using a FILE STATUS clause, test the file status key after each input or output statement, and call an error-handling procedure if a nonzero file status code is returned. With VSAM files, you can use a second data item in the FILE STATUS clause to get additional VSAM status code information. Another way of handling errors in input and output operations is to code ERROR (synonymous with EXCEPTION) declaratives.
RELATED TASKS

Handling errors in input and output operations on page 235 Coding ERROR declaratives on page 238 Using file status keys on page 239

150

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 9. Processing QSAM files


Queued sequential access method (QSAM) files are unkeyed files in which the records are placed one after another, according to entry order. Your program can process these files only sequentially, retrieving (with the READ statement) records in the same order as they are in the file. Each record is placed after the preceding record. To process QSAM files in your program, use COBOL language statements that: v Identify and describe the QSAM files in the ENVIRONMENT DIVISION and the DATA DIVISION. v Process the records in these files in the PROCEDURE DIVISION. After you have created a record, you cannot change its length or its position in the file, and you cannot delete it. You can, however, update QSAM files on direct-access storage devices (using REWRITE), though not in the HFS. QSAM files can be on tape, direct-access storage devices (DASDs), unit-record devices, and terminals. QSAM processing is best for tables and intermediate storage. You can also access byte-stream files in the HFS using QSAM. These files are binary byte-oriented sequential files with no record structure. The record definitions that you code in your COBOL program and the length of the variables that you read into and write from determine the amount of data transferred.
RELATED CONCEPTS

Labels for QSAM files on page 174 z/OS DFSMS: Using Data Sets (Access methods)
RELATED TASKS

Defining QSAM files and records in COBOL Coding input and output statements for QSAM files on page 161 Handling errors in QSAM files on page 165 Working with QSAM files on page 166 Processing QSAM ASCII files on tape on page 177 Processing ASCII file labels on page 178

Defining QSAM files and records in COBOL


Use the FILE-CONTROL entry to define the files in a COBOL program as QSAM files, and to associate the files with their external file-names. An external file-name (a ddname or environment variable name) is the name by which a file is known to the operating system. In the following example, COMMUTER-FILE-MST is your programs name for the file; COMMUTR is the external name:
FILE-CONTROL. SELECT COMMUTER-FILE-MST ASSIGN TO S-COMMUTR ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL.

Copyright IBM Corp. 1991, 2009

151

The ASSIGN clause name can include an S- before the external name to document that the file is a QSAM file. Both the ORGANIZATION and ACCESS MODE clauses are optional.
RELATED TASKS

Establishing record formats Setting block sizes on page 159

Establishing record formats


In the FD entry in the DATA DIVISION, code the record format and indication of whether the records are blocked. In the associated record description entry or entries, specify the record-name and record length. You can code a record format of F, V, S, or U in the RECORDING MODE clause. COBOL determines the record format from the RECORD clause or from the record descriptions associated with the FD entry for the file. If you want the records to be blocked, code the BLOCK CONTAINS clause in the FD entry. The following example shows how the FD entry might look for a file that has fixed-length records:
FILE SECTION. FD COMMUTER-FILE-MST RECORDING MODE IS F BLOCK CONTAINS 0 RECORDS RECORD CONTAINS 80 CHARACTERS. 01 COMMUTER-RECORD-MST. 05 COMMUTER-NUMBER PIC X(16). 05 COMMUTER-DESCRIPTION PIC X(64).

A recording mode of S is not supported for files in the HFS. The above example is appropriate for such a file.
RELATED CONCEPTS

Logical records
RELATED TASKS

Requesting fixed-length format on page 153 Requesting variable-length format on page 154 Requesting spanned format on page 156 Requesting undefined format on page 158 Defining QSAM files and records in COBOL on page 151
RELATED REFERENCES

FILE SECTION entries on page 14

Logical records
COBOL uses the term logical record in a slightly different way than z/OS QSAM. For format-V and format-S files, a QSAM logical record includes a 4-byte prefix in front of the user data portion of the record that is not included in the definition of a COBOL logical record. For format-F and format-U files, and for HFS byte-stream files, the definitions of QSAM logical record and COBOL logical record are identical.

152

Enterprise COBOL for z/OS V4.2 Programming Guide

In this information, QSAM logical record refers to the QSAM definition, and logical record refers to the COBOL definition.
RELATED REFERENCES

Layout Layout Layout Layout

of of of of

format-F records format-V records on page 155 format-S records on page 157 format-U records on page 159

Requesting fixed-length format


Fixed-length records are in format F. Use RECORDING MODE F to explicitly request this format. You can omit the RECORDING MODE clause. The compiler determines the recording mode to be F if the length of the largest level-01 record associated with the file is not greater than the block size coded in the BLOCK CONTAINS clause, and you take one of the following actions: v Use the RECORD CONTAINS integer clause (format-1 RECORD clause) to indicate the length of the record in bytes. When you use this clause, the file is always fixed format with record length integer even if there are multiple level-01 record description entries with different lengths associated with the file. v Omit the RECORD CONTAINS integer clause, but code the same fixed size and no OCCURS DEPENDING ON clause for all level-01 record description entries associated with the file. This fixed size is the record length. In an unblocked format-F file, the logical record is the same as the block. In a blocked format-F file, the number of logical records in a block (the blocking factor) is constant for every block in the file except the last block, which might be shorter. Files in the HFS are never blocked.
RELATED CONCEPTS

Logical records on page 152


RELATED TASKS

Requesting variable-length format on page 154 Requesting spanned format on page 156 Requesting undefined format on page 158 Establishing record formats on page 152
RELATED REFERENCES

Layout of format-F records Layout of format-F records: The layout of format-F QSAM records is shown below.

Chapter 9. Processing QSAM files

153

RELATED CONCEPTS

Logical records on page 152


RELATED TASKS

Requesting fixed-length format on page 153 z/OS DFSMS: Using Data Sets (Fixed-length record formats)
RELATED REFERENCES

Layout of format-V records on page 155 Layout of format-S records on page 157 Layout of format-U records on page 159

Requesting variable-length format


Variable-length records can be in format V or format D. Format-D records are variable-length records on ASCII tape files. Format-D records are processed in the same way as format-V records. Use RECORDING MODE V for both. You can omit the RECORDING MODE clause. The compiler determines the recording mode to be V if the largest level-01 record associated with the file is not greater than the block size set in the BLOCK CONTAINS clause, and you take one of the following actions: v Use the RECORD IS VARYING clause (format-3 RECORD clause). If you provide values for integer-1 and integer-2 (RECORD IS VARYING FROM integer-1 TO integer-2), the maximum record length is the value coded for integer-2 regardless of the lengths coded in the level-01 record description entries associated with the file. The integer sizes indicate the minimum and maximum record lengths in numbers of bytes regardless of the USAGE of the data items in the record. If you omit integer-1 and integer-2, the maximum record length is determined to be the size of the largest level-01 record description entry associated with the file. v Use the RECORD CONTAINS integer-1 TO integer-2 clause (format-2 RECORD clause). Make integer-1 and integer-2 match the minimum length and the maximum length in bytes of the level-01 record description entries associated with the file. The maximum record length is the integer-2 value. v Omit the RECORD clause, but code multiple level-01 records (associated with the file) that are of different sizes or contain an OCCURS DEPENDING ON clause. The maximum record length is determined to be the size of the largest level-01 record description entry associated with the file. When you specify a READ INTO statement for a format-V file, the record size read for that file is used in the MOVE statement generated by the compiler. Consequently, you might not get the result you expect if the record just read does not correspond to the level-01 record description. All other rules of the MOVE statement apply. For

154

Enterprise COBOL for z/OS V4.2 Programming Guide

example, when you specify a MOVE statement for a format-V record read in by the READ statement, the size of the record moved corresponds to its level-01 record description. When you specify a READ statement for a format-V file followed by a MOVE of the level-01 record, the actual record length is not used. The program will attempt to move the number of bytes described by the level-01 record description. If this number exceeds the actual record length and extends outside the area addressable by the program, results are unpredictable. If the number of bytes described by the level-01 record description is shorter than the physical record read, truncation of bytes beyond the level-01 description occurs. To find the actual length of a variable-length record, specify data-name-1 in format 3 of the RECORD clause of the File Definition (FD).
RELATED TASKS

Requesting fixed-length format on page 153 Requesting spanned format on page 156 Requesting undefined format on page 158 Establishing record formats on page 152
RELATED REFERENCES

FILE SECTION entries on page 14 Layout of format-V records Enterprise COBOL Compiler and Runtime Migration Guide (Moving from the VS COBOL II run time) Layout of format-V records: Format-V QSAM records have control fields that precede the data. The QSAM logical record length is determined by adding 4 bytes (for the control fields) to the record length defined in your program, but you must not include these 4 bytes in the description of the record and record length.

CC

The first 4 bytes of each block contain control information. LL Represents 2 bytes designating the length of the block (including the CC field). BB Represents 2 bytes reserved for system use.

cc

The first 4 bytes of each logical record contain control information. ll Represents 2 bytes designating the logical record length (including the cc field). bb Represents 2 bytes reserved for system use.

The block length is determined as follows: v Unblocked format-V records: CC + cc + the data portion
Chapter 9. Processing QSAM files

155

v Blocked format-V records: CC + the cc of each record + the data portion of each record The operating system provides the control bytes when the file is written; the control byte fields do not appear in your description of the logical record in the DATA DIVISION of your program. COBOL allocates input and output buffers large enough to accommodate the control bytes. These control fields in the buffer are not available for you to use in your program. When variable-length records are written on unit record devices, control bytes are neither printed nor punched. They appear, however, on other external storage devices, as well as in buffer areas of storage. If you move V-mode records from an input buffer to a WORKING-STORAGE area, theyll be moved without the control bytes. Files in the HFS are never blocked.
RELATED CONCEPTS

Logical records on page 152


RELATED TASKS

Requesting variable-length format on page 154


RELATED REFERENCES

Layout of format-F records on page 153 Layout of format-S records on page 157 Layout of format-U records on page 159

Requesting spanned format


Spanned records are in format S. A spanned record is a QSAM logical record that can be contained in one or more physical blocks. You can code RECORDING MODE S for spanned records in QSAM files that are assigned to magnetic tape or to direct access devices. Do not request spanned records for files in the HFS. You can omit the RECORDING MODE clause. The compiler determines the recording mode to be S if the maximum record length (in bytes) plus 4 is greater than the block size set in the BLOCK CONTAINS clause. For files with format S in your program, the compiler determines the maximum record length with the same rules as are used for format V. The length is based on your usage of the RECORD clause. When creating files that contain format-S records and a record is larger than the remaining space in a block, COBOL writes a segment of the record to fill the block. The rest of the record is stored in the next block or blocks depending on its length. COBOL supports QSAM spanned records up to 32,760 bytes in length. When retrieving files that have format-S records, a program can retrieve only complete records. Benefits of format-S files: You can efficiently use external storage and still organize your files with logical record lengths by defining files with format-S records: v You can set block lengths to efficiently use track capacities on direct access devices. v You are not required to adjust the logical record lengths to device-dependent physical block lengths. One logical record can span two or more physical blocks.

156

Enterprise COBOL for z/OS V4.2 Programming Guide

v You have greater flexibility when you want to transfer logical records between direct access storage types. You will, however, have additional overhead in processing format-S files. Format-S files and READ INTO: When you specify a READ INTO statement for a format-S file, the compiler generates a MOVE statement that uses the size of the record that it just read for that file. If the record just read does not correspond to the level-01 record description, you might not get the result that you expect. All other rules of the MOVE statement apply.
RELATED CONCEPTS

Logical records on page 152 Spanned blocked and unblocked files


RELATED TASKS

Requesting fixed-length format on page 153 Requesting variable-length format on page 154 Requesting undefined format on page 158 Establishing record formats on page 152
RELATED REFERENCES

FILE SECTION entries on page 14 Layout of format-S records Spanned blocked and unblocked files: A spanned blocked QSAM file is made up of blocks, each containing one or more logical records or segments of logical records. A spanned unblocked file is made up of physical blocks, each containing one logical record or one segment of a logical record. In a spanned blocked file, a logical record can be either fixed or variable in length, and its size can be smaller than, equal to, or larger than the physical block size. There are no required relationships between logical records and physical block sizes. In a spanned unblocked file, the logical records can be either fixed or variable in length. When the physical block contains one logical record, the block length is determined by the logical record size. When a logical record has to be segmented, the system always writes the largest physical block possible. The system segments the logical record when the entire logical record cannot fit on a track.
RELATED CONCEPTS

Logical records on page 152


RELATED TASKS

Requesting spanned format on page 156 Layout of format-S records: Spanned records are preceded by control fields, as shown below.

Chapter 9. Processing QSAM files

157

Each block is preceded by a 4-byte block descriptor field (BDF in the image). There is only one block descriptor field at the beginning of each physical block. Each segment of a record in a block, even if the segment is the entire record, is preceded by a 4-byte segment descriptor field (SDF in the image). There is one segment descriptor field for each record segment in the block. The segment descriptor field also indicates whether the segment is the first, the last, or an intermediate segment. You do not describe these fields in the DATA DIVISION of your COBOL program, and the fields are not available for you to use in your program.
RELATED TASKS

Requesting spanned format on page 156


RELATED REFERENCES

Layout of format-F records on page 153 Layout of format-V records on page 155 Layout of format-U records on page 159

Requesting undefined format


Format-U records have undefined or unspecified characteristics. With format U, you can process blocks that do not meet format-F or format-V specifications. When you use format-U files, each block of storage is one logical record. A read of a format-U file returns the entire block as a record. A write to a format-U file writes a record out as a block. The compiler determines the recording mode to be U only if you code RECORDING MODE U. It is recommended that you not use format U to update or extend a file that was written with a different record format. If you use format U to update a file that was written with a different format, the RECFM value in the data-set label could be changed or the data set could contain records written in different formats. The record length is determined in your program based on how you use the RECORD clause: v If you use the RECORD CONTAINS integer clause (format-1 RECORD clause), the record length is the integer value regardless of the lengths of the level-01 record description entries associated with the file. The integer size indicates the number of bytes in a record regardless of the USAGE of its data items. v If you use the RECORD IS VARYING clause (format-3 RECORD clause), the record length is determined based on whether you code integer-1 and integer-2. If you code integer-1 and integer-2 (RECORD IS VARYING FROM integer-1 TO integer-2), the maximum record length is the integer-2 value regardless of the lengths of the level-01 record description entries associated with the file. The integer sizes indicate the minimum and maximum record lengths in numbers of bytes regardless of the USAGE of the data items in the record. If you omit integer-1 and integer-2, the maximum record length is determined to be the size of the largest level-01 record description entry associated with the file. v If you use the RECORD CONTAINS integer-1 TO integer-2 clause (format-2 RECORD clause), with integer-1 and integer-2 matching the minimum length and the maximum length in bytes of the level-01 record description entries associated with the file, the maximum record length is the integer-2 value.

158

Enterprise COBOL for z/OS V4.2 Programming Guide

v If you omit the RECORD clause, the maximum record length is determined to be the size of the largest level-01 record description entry associated with the file. Format-U files and READ INTO: When you specify a READ INTO statement for a format-U file, the compiler generates a MOVE statement that uses the size of the record that it just read for that file. If the record just read does not correspond to the level-01 record description, you might not get the result that you expect. All other rules of the MOVE statement apply.
RELATED TASKS

Requesting fixed-length format on page 153 Requesting variable-length format on page 154 Requesting spanned format on page 156 Establishing record formats on page 152
RELATED REFERENCES

FILE SECTION entries on page 14 Layout of format-U records Layout of format-U records: With format-U, each block of external storage is handled as a logical record. There are no record-length or block-length fields.

RELATED CONCEPTS

Logical records on page 152


RELATED TASKS

Requesting undefined format on page 158


RELATED REFERENCES

Layout of format-F records on page 153 Layout of format-V records on page 155 Layout of format-S records on page 157

Setting block sizes


In COBOL, you establish the size of a physical record by using the BLOCK CONTAINS clause. If you omit this clause, the compiler assumes that the records are not blocked. Blocking QSAM files on tape and disk can enhance processing speed and minimize storage requirements. You can block files in the z/OS UNIX file system, PDSE members, and spooled data sets, but doing so has no effect on how the system stores the data. If you set the block size explicitly in the BLOCK CONTAINS clause, the size must not be greater than the maximum block size for the device. If you specify the CHARACTERS phrase of the BLOCK CONTAINS clause, size must indicate the number of bytes in a record regardless of the USAGE of the data items in the record. The block size that is set for a format-F file must be an integral multiple of the record length.
Chapter 9. Processing QSAM files

159

If your program uses QSAM files on tape, use a physical block size of at least 12 to 18 bytes. Otherwise, the block will be skipped over when a parity check occurs during one of the following actions: v Reading a block of records of fewer than 12 bytes v Writing a block of records of fewer than 18 bytes Larger blocks generally give you better performance. Blocks of only a few kilobytes are particularly inefficient; you should choose a block size of at least tens of kilobytes. If you specify record blocking and omit the block size, the system will pick a block size that is optimal for device utilization and for data transfer speed. Letting z/OS determine block size: To maximize performance, do not explicitly set the block size for a blocked file in your COBOL source program. For new blocked data sets, it is simpler to allow z/OS to supply a system-determined block size. To use this feature, follow these guidelines: v Code BLOCK CONTAINS 0 in your source program. v Do not code RECORD CONTAINS 0 in your source program. v Do not code a BLKSIZE value in the JCL DD statement. Setting block size explicitly: If you prefer to set a block size explicitly, your program will be most flexible if you follow these guidelines: v Code BLOCK CONTAINS 0 in your source program. v Code a BLKSIZE value in the ddname definition (the JCL DD statement). For extended-format data sets on z/OS, z/OS DFSMS adds a 32-byte block suffix to the physical record. If you specify a block size explicitly (using JCL or ISPF), do not include the size of this block suffix in the block size. This block suffix is not available for you to use in your program. z/OS DFSMS allocates the space used to read in the block suffix. However, when you calculate how many blocks of an extended-format data set will fit on a track of a direct-access device, you need to include the size of the block suffix in the block size. If you specify a block size that is larger than 32760 directly in the BLOCK CONTAINS clause or indirectly with the use of BLOCK CONTAINS n RECORDS, the OPEN of the data set fails with file status code 90 unless you define the data set to be on tape. For existing blocked data sets, it is simplest to: v Code BLOCK CONTAINS 0 in your source program. v Not code a BLKSIZE value in the ddname definition. When you omit the BLKSIZE from the ddname definition, the block size is automatically obtained by the system from the data-set label. Taking advantage of LBI: You can improve the performance of tape data sets by using the large block interface (LBI) for large block sizes. When the LBI is available, the COBOL run time automatically uses this facility for those tape files for which you use system-determined block size. LBI is also used for those files for which you explicitly define a block size in JCL or a BLOCK CONTAINS clause. Use of the LBI allows block sizes to exceed 32760 if the tape device supports it. The LBI is not used in all cases. An attempt to use a block size greater than 32760 in the following cases is diagnosed at compile time or results in a failure at OPEN: v Spanned records

160

Enterprise COBOL for z/OS V4.2 Programming Guide

v OPEN I-O Using a block size that exceeds 32760 might result in your not being able to read the tape on another system. A tape that you create with a block size greater than 32760 can be read only on a system that has a tape device that supports block sizes greater than 32760. If you specify a block size that is too large for the file, the device, or the operating system level, a runtime message is issued. To limit a system-determined block size to 32760, do not specify BLKSIZE anywhere, and set one of the following items to 32760: v The BLKSZLIM keyword on the DD statement for the data set v BLKSZLIM for the data class by using the BLKSZLIM keyword (must be set by your systems programmer) v A block-size limit for the system in the DEVSUPxx member of SYS1.PARMLIB by using the keyword TAPEBLKSZLIM (must be set by your systems programmer) The block-size limit is the first nonzero value that the compiler finds by checking these items. If no BLKSIZE or BLKSZLIM value is available from any source, the system limits BLKSIZE to 32760. You can then enable block sizes larger than 32760 in one of two ways: v Specify a BLKSZLIM value greater than 32760 in the DD statement for the file and use BLOCK CONTAINS 0 in your COBOL source. v Specify a value greater than 32760 for the BLKSIZE in the DD statement or in the BLOCK CONTAINS clause in your COBOL source. BLKSZLIM is device-independent. Block size and the DCB RECFM subparameter: Under z/OS, you can code the S or T option in the DCB RECFM subparameter: v Use the S (standard) option in the DCB RECFM subparameter for a format-F record with only standard blocks (ones that have no truncated blocks or unfilled tracks in the file, except for the last block of the file). S is also supported for records on tape. It is ignored if the records are not on DASD or tape. Using this standard block option might improve input-output performance, especially for direct-access devices. v The T (track overflow) option for QSAM files is no longer useful.
RELATED TASKS

Defining QSAM files and records in COBOL on page 151 z/OS DFSMS: Using Data Sets
RELATED REFERENCES

FILE SECTION entries on page 14 BLOCK0 on page 307 BLOCK CONTAINS clause (Enterprise COBOL Language Reference)

Coding input and output statements for QSAM files


You can code the following input and output statements to process a QSAM file or a byte-stream file in the HFS using QSAM: OPEN, READ, WRITE, REWRITE, and CLOSE.

Chapter 9. Processing QSAM files

161

OPEN

Initiates the processing of files. You can open all QSAM files as INPUT, OUTPUT, or EXTEND (depending on device capabilities). You can also open QSAM files on direct access storage devices as I-O. You cannot open HFS files as I-O; a file status of 37 results if you attempt to do so.

READ

Reads a record from the file. With sequential processing, your program reads one record after another in the same order in which they were entered when the file was created. Creates a record in the file. Your program writes new records to the end of the file. Updates a record. You cannot update a file in the HFS using REWRITE.

WRITE REWRITE CLOSE

Releases the connection between the file and your program.

RELATED TASKS

Opening QSAM files Adding records to QSAM files on page 163 Updating QSAM files on page 164 Writing QSAM files to a printer or spooled data set on page 164 Closing QSAM files on page 165
RELATED REFERENCES

OPEN statement (Enterprise COBOL Language Reference) READ statement (Enterprise COBOL Language Reference) WRITE statement (Enterprise COBOL Language Reference) REWRITE statement (Enterprise COBOL Language Reference) CLOSE statement (Enterprise COBOL Language Reference) File status key (Enterprise COBOL Language Reference)

Opening QSAM files


Before your program can use any READ, WRITE, or REWRITE statements to process records in a file, it must first open the file with an OPEN statement. An OPEN statement works if both of the following conditions are true: v The file is available or has been dynamically allocated. v The fixed file attributes coded in the ddname definition or the data-set label for the file match the attributes coded for that file in the SELECT clause and FD entry. Mismatches in the file-organization attributes, code set, maximum record size, or record format (fixed or variable) result in a file status code 39, and the failure of the OPEN statement. Mismatches in maximum record size and record format are not errors when opening files in the HFS. For fixed-length QSAM files, if you code RECORD CONTAINS 0 in the FD entry, the record size attributes are not in conflict. The record size is taken from the DD statement or the data-set label, and the OPEN statement is successful. Code CLOSE WITH LOCK so that the file cannot be opened again while the program is running.

162

Enterprise COBOL for z/OS V4.2 Programming Guide

Use the REVERSED option of the OPEN statement to process tape files in reverse order. The file is positioned at the end, and READ statements read the data records in reverse order, starting with the last record. The REVERSED option is supported only for files that have fixed-length records.
RELATED TASKS

Dynamically creating QSAM files Ensuring that file attributes match your program on page 170
RELATED REFERENCES

OPEN statement (Enterprise COBOL Language Reference)

Dynamically creating QSAM files


Sometimes a QSAM file is unavailable on the operating system, but a COBOL program specifies that the file be created. Under certain circumstances, the file is created for you dynamically. A QSAM file is considered to be available on z/OS when it has been identified to the operating system using a valid DD statement, an export command for an environment variable, or a TSO ALLOCATE command. Otherwise the file is unavailable. Note that a DD statement with a misspelled ddname is equivalent to a missing DD statement, and an environment variable with a value that is not valid is equivalent to an unset variable. The QSAM file is implicitly created if you use the runtime option CBLQDA and one of the following circumstances exists: v An optional file is being opened as EXTEND or I-O. Optional files are files that are not necessarily available each time the program is run. You define a file that is being opened in INPUT, I-O, or EXTEND mode as optional by coding the SELECT OPTIONAL clause in the FILE-CONTROL paragraph. v The file is being opened for OUTPUT, regardless of the OPTIONAL phrase. The file is allocated with the system default attributes established at your installation and the attributes coded in the SELECT clause and FD entry in your program. Do not confuse this implicit allocation mechanism with the explicit dynamic allocation of files by means of environment variables. Explicit dynamic allocation requires that a valid environment variable be set. CBLQDA support is used only when the QSAM file is unavailable as defined above, which includes no valid environment variable being set. Under z/OS, files created using the CBLQDA option are temporary data sets and do not exist after the program has run.
RELATED TASKS

Opening QSAM files on page 162

Adding records to QSAM files


To add to a QSAM file, open the file as EXTEND and use the WRITE statement to add records immediately after the last record in the file.
Chapter 9. Processing QSAM files

163

To add records to a file opened as I-O, you must first close the file and open it as EXTEND.
RELATED REFERENCES

READ statement (Enterprise COBOL Language Reference) WRITE statement (Enterprise COBOL Language Reference)

Updating QSAM files


You can update QSAM files only if they reside on direct access storage devices. You cannot update files in the HFS. Replace an existing record with another record of the same length by doing these steps: 1. Open the file as I-O. 2. Use REWRITE to update an existing record. (The last file processing statement before REWRITE must have been a successful READ statement.) You cannot open as I-O an extended format data set that you allocate in compressed format.
RELATED REFERENCES

REWRITE statement (Enterprise COBOL Language Reference)

Writing QSAM files to a printer or spooled data set


COBOL provides language statements to control the size of a printed page and control the vertical positioning of records. Controlling the page size: Use the LINAGE clause of the FD entry to control the size of your printed page: the number of lines in the top and bottom margins and in the footing area of the page. When you use the LINAGE clause, COBOL handles the file as if you had also requested the ADV compiler option. If you use the LINAGE clause in combination with WRITE BEFORE|AFTER ADVANCING nn LINES, be careful about the values you set. With the ADVANCING nn LINES phrase, COBOL first calculates the sum of LINAGE-COUNTER plus nn. Subsequent actions depend on the size of nn. The END-OF-PAGE imperative phrase is performed after the LINAGE-COUNTER is increased. Consequently, the LINAGE-COUNTER could be pointing to the next logical page instead of to the current footing area when the END-OF-PAGE phrase is performed. AT END-OF-PAGE or NOT AT END-OF-PAGE imperative phrases are performed only if the write operation completes successfully. If the write operation is unsuccessful, control is passed to the end of the WRITE statement, and all conditional phrases are omitted. Controlling the vertical positioning of records: Use the WRITE ADVANCING statement to control the vertical positioning of each record you write on a printed page. BEFORE ADVANCING prints the record before the page is advanced. AFTER ADVANCING prints the record after the page is advanced.

164

Enterprise COBOL for z/OS V4.2 Programming Guide

Specify the number of lines the page is advanced with an integer (or an identifier with a mnemonic-name) following ADVANCING. If you omit the ADVANCING phrase from a WRITE statement, the effect is as if you had coded:
AFTER ADVANCING 1 LINE
RELATED REFERENCES

WRITE statement (Enterprise COBOL Language Reference)

Closing QSAM files


Use the CLOSE statement to disconnect your program from a QSAM file. If you try to close a file that is already closed, you will get a logic error. If you do not close a QSAM file, the file is automatically closed for you under the following conditions, except for files defined in any OS/VS COBOL programs in the run unit: v When the run unit ends normally, the run time closes all open files that are defined in any COBOL programs in the run unit. v If the run unit ends abnormally and the TRAP(ON) runtime option is in effect, the run time closes all open files that are defined in any COBOL programs in the run unit. v When Language Environment condition handling has completed and the application resumes in a routine other than where the condition occurred, the run time closes all open files that are defined in any COBOL programs in the run unit that might be called again and reentered. You can change the location where the program resumes running (after a condition is handled) by moving the resume cursor with the Language Environment CEEMRCR callable service or by using language constructs such as a C longjmp. v When you use CANCEL for a COBOL subprogram, the run time closes any open nonexternal files that are defined in that program. v When a COBOL subprogram with the INITIAL attribute returns control, the run time closes any open nonexternal files that are defined in that program. v When a thread of a multithreaded application ends, both external and nonexternal files that you opened from within that same thread are closed. File status key data items in the DATA DIVISION are set when these implicit CLOSE operations are performed, but your EXCEPTION/ERROR and LABEL declaratives are not invoked. Errors: If you open a QSAM file in a multithreaded application, you must close it from the same thread of execution from which the file was opened. Attempting to close the file from a different thread results in a close failure with file-status condition 90.
RELATED REFERENCES

CLOSE statement (Enterprise COBOL Language Reference)

Handling errors in QSAM files


When an input statement or output statement fails, COBOL does not take corrective action for you. You choose whether your program should continue running after a less-than-severe input or output error occurs.
Chapter 9. Processing QSAM files

165

COBOL provides these ways for you to intercept and handle certain QSAM input and output errors: v End-of-file phrase (AT END) v EXCEPTION/ERROR declarative v FILE STATUS clause v INVALID KEY phrase If you do not code a FILE STATUS key or a declarative, serious QSAM processing errors will cause a message to be issued and a Language Environment condition to be signaled, which will cause an abend if you specify the runtime option ABTERMENC(ABEND). If you use the FILE STATUS clause or the EXCEPTION/ERROR declarative, code EROPT=ACC in the DCB of the DD statement for that file. Otherwise, your COBOL program will not be able to continue processing after some error conditions. If you use the FILE STATUS clause, be sure to check the key and take appropriate action based on its value. If you do not check the key, your program might continue, but the results will probably not be what you expected.
RELATED TASKS

Handling errors in input and output operations on page 235

Working with QSAM files


To work with QSAM files in a COBOL program, you define and allocate them, retrieve them, and ensure that their file attributes match those in your program. You can also use striped extended-format QSAM data sets to help improve performance.
RELATED TASKS

Defining and allocating QSAM files Retrieving QSAM files on page 169 Ensuring that file attributes match your program on page 170 Using striped extended-format QSAM data sets on page 172
RELATED REFERENCES

Allocation of buffers for QSAM files on page 173

Defining and allocating QSAM files


You can define a QSAM file or a byte-stream file in the HFS by using either a DD statement or an environment variable. Allocation of these files follows the general rules for the allocation of COBOL files. When you use an environment variable, the name must be in uppercase. Specify the MVS data set in one of these ways: v DSN(dataset-name) v DSN(dataset-name(member-name)) dataset-name must be fully qualified and cannot be a temporary data set (that is, it must not start with &).

166

Enterprise COBOL for z/OS V4.2 Programming Guide

Restriction: You cannot create a PDS or PDSE by using an environment variable. You can optionally specify the following attributes in any order after DSN: v v v v v v v v A disposition value, one of: NEW, OLD, SHR, or MOD TRACKS or CYL SPACE(nnn,mmm) VOL(volume-serial) UNIT(type) KEEP, DELETE, CATALOG, or UNCATALOG STORCLAS(storage-class) MGMTCLAS(management-class)

v DATACLAS(data-class) You can use either an environment variable or a DD definition to define a file in the HFS. To do so, define one of the following items with a name that matches the external name in the ASSIGN clause: v A DD allocation that uses PATH='absolute-path-name' and FILEDATA=BINARY v An environment variable with a value PATH(pathname), where pathname is an absolute path name (starting with /) For compatibility with releases of COBOL before COBOL for OS/390 & VM Version 2 Release 2, you can also specify FILEDATA=TEXT when using a DD allocation for HFS files, but this use is not recommended. To process text files in the HFS, use LINE SEQUENTIAL organization. If you do use QSAM to process text files in the HFS, you cannot use environment variables to define the files. When you define a QSAM file, use the parameters as shown below.
Table 20. QSAM file allocation What you want to do Name the file. Select the type and quantity of input-output devices to be allocated for the file. DD parameter to use DSNAME (data-set name) UNIT EV keyword to use DSN UNIT for type only

Give instructions for the volume in VOLUME (or let the system VOL which the file will reside and for choose an output volume) volume mounting. Allocate the type and amount of space the file needs. (Only for direct-access storage devices.) Specify the type and some of the contents of the label associated with the file. Indicate whether you want to catalog, pass, or keep the file after the job step is completed. Complete any data control block information that you want to add. SPACE SPACE for the amount of space (primary and secondary only); TRACKS or CYL for the type of space n/a

LABEL

DISP

NEW, OLD, SHR, MOD plus KEEP, DELETE, CATALOG, or UNCATALOG n/a

DCB subparameters

Chapter 9. Processing QSAM files

167

Some of the information about the QSAM file must always be coded in the FILE-CONTROL paragraph, the FD entry, and other COBOL clauses. Other information must be coded in the DD statement or environment variable for output files. For input files, the system can obtain information from the file label (for standard label files). If DCB information is provided in the DD statement for input files, it overrides information on the data-set label. For example, the amount of space allocated for a new direct-access device file can be set in the DD statement by the SPACE parameter. You cannot express certain characteristics of QSAM files in the COBOL language, but you can code them in the DD statement for the file by using the DCB parameter. Use the subparameters of the DCB parameter to provide information that the system needs for completing the data set definition, including the following items: v Block size (BLKSIZE=), if BLOCK CONTAINS 0 RECORDS was coded at compile time (recommended) v Options to be executed if an error occurs in reading or writing a record v TRACK OVERFLOW or standard blocks v Mode of operation for a card reader or punch DCB attributes coded for a DD DUMMY do not override those coded in the FD entry of your COBOL program. Example: setting and accessing environment variables on page 440
RELATED TASKS

Setting block sizes on page 159 Defining QSAM files and records in COBOL on page 151 Allocating files on page 149
RELATED REFERENCES

Parameters for creating QSAM files on page 169 MVS Program Management: Users Guide and Reference

168

Enterprise COBOL for z/OS V4.2 Programming Guide

Parameters for creating QSAM files


The following DD statement parameters are frequently used to create QSAM files.

DSNAME= DSN=

dataset-name dataset-name(member-name) &&name &&name(member-name) ( name[,unitcount] )

UNIT=

VOLUME= ( [PRIVATE] [,RETAIN] [,vol-sequence-num] [,volume-count] ... VOL= ... ,SER=(volume-serial[,volume-serial]...) ( ,REF= dsname *.ddname *.stepname.ddname *.stepname.procstep.ddname SPACE= ( TRK ,(primary-quantity[,secondary-quantity][,directory-quantity])) CYL average-record-length LABEL= ( [Data-set-sequence-number,] NL SL SUL DISP=
( NEW MOD ,DELETE ,KEEP ,PASS ,CATLG ,DELETE ,KEEP ,CATLG ) yyddd yyyy/ddd ,RETPD=xxxx ,EXPDT= (

DCB=

( subparameter-list )

RELATED TASKS

Defining and allocating QSAM files on page 166

Retrieving QSAM files


You retrieve QSAM files, cataloged or not, by using job control statements or environment variables. Cataloged files All data set information, such as volume and space, is stored in the catalog and file label. All you have to code are the data set name and a disposition. When you use a DD statement, this is the DSNAME parameter and the DISP parameter. When you use an environment variable, this is the DSN parameter and one of the parameters OLD, SHR, or MOD. Noncataloged files Some information is stored in the file label, but you must code the unit and volume information, and the dsname and disposition. If you are using JCL, and you created the file in the current job step or in a previous job step in the current job, you can refer to the previous DD statement for most of the data set information. You do, however, need to code DSNAME and DISP.
RELATED REFERENCES

Parameters for retrieving QSAM files on page 170

Chapter 9. Processing QSAM files

169

Parameters for retrieving QSAM files


The following DD statement parameters are used to retrieve previously created files.

RELATED TASKS

Retrieving QSAM files on page 169

Ensuring that file attributes match your program


When the fixed file attributes in the DD statement or the data-set label and the attributes that are coded for that file in the SELECT clause and FD entry are not consistent, an OPEN statement in your program might not work. Mismatches in the attributes for file organization, record format (fixed or variable), record length, or the code set result in file status code 39 and the failure of the OPEN statement. An exception exists for files in the HFS: mismatches in record format and record length do not cause an error. To prevent common file status 39 problems, follow the guidelines for processing existing or new files. If you have not made a file available with a DD statement or a TSO ALLOCATE command, and your COBOL program specifies that the file be created, Enterprise COBOL dynamically allocates the file. When the file is opened, the file attributes that are coded in your program are used. You do not have to worry about file attribute conflicts. Remember that information in the JCL or environment variable overrides information in the data-set label.

170

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED TASKS

Processing existing files Processing new files on page 172 Opening QSAM files on page 162
RELATED REFERENCES

FILE SECTION entries on page 14

Processing existing files


When your program processes an existing file, code the description of the file in your COBOL program to be consistent with the file attributes of the data set. Use the guidelines below to define the maximum record length.
Table 21. Maximum record length of QSAM files For this format: V or S F U Specify this: Exactly 4 bytes less than the length attribute of the data set Same value as the length attribute of the data set Same value as the length attribute of the data set

The easiest way to define variable-length (format-V) records in a program is to use the RECORD IS VARYING FROM integer-1 TO integer-2 clause in the FD entry and set an appropriate value for integer-2. Express the integer sizes in bytes regardless of the underlying USAGE of the data items in the record. For example, assume that you determine that the length attribute of the data set is 104 bytes (LRECL=104). Remembering that the maximum record length is determined from the RECORD IS VARYING clause and not from the level-01 record descriptions, you could define a format-V file in your program with this code:
FILE SECTION. FD COMMUTER-FILE-MST RECORDING MODE IS V RECORD IS VARYING FROM 4 TO 100 CHARACTERS. 01 COMMUTER-RECORD-A PIC X(4). 01 COMMUTER-RECORD-B PIC X(75).

Assume that the existing file in the previous example was format-U instead of format-V. If the 104 bytes are all user data, you could define the file in your program with this code:
FILE SECTION. FD COMMUTER-FILE-MST RECORDING MODE IS U RECORD IS VARYING FROM 4 TO 104 CHARACTERS. 01 COMMUTER-RECORD-A PIC X(4). 01 COMMUTER-RECORD-B PIC X(75).

To define fixed-length records in your program, either code the RECORD CONTAINS integer clause, or omit this clause and code all level-01 record descriptions to be the same fixed size. In either case, use a value that equals the value of the length attribute of the data set. If you intend to use the same program to process different files at run time, and those files have differing fixed lengths, avoid record-length conflicts by coding RECORD CONTAINS 0. If the existing file is an ASCII data set (DCB=(OPTCD=Q)), you must use the CODE-SET clause in the FD entry for the file.

Chapter 9. Processing QSAM files

171

RELATED TASKS

Processing new files Requesting fixed-length format on page 153 Requesting variable-length format on page 154 Requesting undefined format on page 158 Opening QSAM files on page 162
RELATED REFERENCES

FILE SECTION entries on page 14

Processing new files


If your COBOL program writes records to a new file that will be made available before the program runs, ensure that the file attributes in the DD statement, the environment variable, or the allocation do not conflict with the attributes in the program. Usually you need to code only a minimum of parameters when predefining files. But if you need to explicitly set a length attribute for the data set (for example, you are using an ISPF allocation panel, or your DD statement is for a batch job in which the program uses RECORD CONTAINS 0), follow these guidelines: v For format-V and format-S files, set a length attribute that is 4 bytes larger than that defined in the program. v For format-F and format-U files, set a length attribute that is the same as that defined in the program. v If you open the file as OUTPUT and write it to a printer, the compiler might add 1 byte to the record length to account for the carriage-control character, depending on the ADV compiler option and the language used in your program. In such a case, take the added byte into account when coding the LRECL value. For example, if your program contains the following code for a file that has variable-length records, the LRECL value in the DD statement or allocation should be 54.
FILE SECTION. FD COMMUTER-FILE-MST RECORDING MODE IS V RECORD CONTAINS 10 TO 50 CHARACTERS. 01 COMMUTER-RECORD-A PIC X(10). 01 COMMUTER-RECORD-B PIC X(50).
RELATED TASKS

Processing existing files on page 171 Requesting fixed-length format on page 153 Requesting variable-length format on page 154 Requesting undefined format on page 158 Opening QSAM files on page 162 Dynamically creating QSAM files on page 163
RELATED REFERENCES

FILE SECTION entries on page 14

Using striped extended-format QSAM data sets


Striped extended-format QSAM data sets can benefit applications that process files that have large amounts of data or in which the time needed for I/O operations significantly affects overall performance.

172

Enterprise COBOL for z/OS V4.2 Programming Guide

A striped extended-format QSAM data set is an extended-format QSAM data set that is spread over multiple volumes, thus allowing parallel data access. For you to gain the maximum benefit from using QSAM striped data sets, z/OS DFSMS needs to be able to allocate the required number of buffers above the 16-MB line. When you develop applications that contain files allocated to QSAM striped data sets, follow these guidelines: v Avoid using a QSAM striped data set for a file that cannot have buffers allocated above the 16-MB line. v Omit the RESERVE clause in the FILE-CONTROL entry for the file. Doing so lets z/OS DFSMS determine the optimum number of buffers for the data set. v Compile your program with the DATA(31) and RENT compiler options, and make the load module AMODE 31. v Specify the ALL31(ON) runtime option if the file is an EXTERNAL file with format-F, format-V, or format-U records. Note that all striped data sets are extended-format data sets, but not all extended-format data sets are striped.
RELATED TASKS

z/OS DFSMS: Using Data Sets


RELATED REFERENCES

Allocation of buffers for QSAM files

Allocation of buffers for QSAM files


z/OS DFSMS automatically allocates buffers for storing input and output for a QSAM file above or below the 16-MB line as appropriate for the file. Most QSAM files have buffers allocated above the 16-MB line. Exceptions are: v Programs running in AMODE 24. v v v v Programs compiled with the DATA(24) and RENT options. Programs compiled with the NORENT and RMODE(24) options. Programs compiled with the NORENT and RMODE(AUTO) options. EXTERNAL files when the ALL31(OFF) runtime option is specified. To specify the ALL31(ON) runtime option, all programs in the run unit must be capable of running in 31-bit addressing mode. v Files allocated to the TSO terminal. v A file with format-S (spanned) records, if the file is any of the following: An EXTERNAL file (even if ALL31(ON) is specified) A file specified in a SAME RECORD AREA clause of the I-O-CONTROL paragraph A blocked file that is opened I-O and updated using the REWRITE statement
RELATED CONCEPTS

Storage and its addressability on page 42


RELATED TASKS

Using striped extended-format QSAM data sets on page 172

Chapter 9. Processing QSAM files

173

Accessing HFS files using QSAM


You can process byte-stream files in the hierarchical file system (HFS) as ORGANIZATION SEQUENTIAL files using QSAM. To do this, specify as the assignment-name in the ASSIGN clause either a ddname or an environment-variable name. ddname A DD allocation that identifies the file with the keywords PATH= and FILEDATA=BINARY Environment-variable name An environment variable that holds the runtime value of the HFS path for the file Observe the following restrictions: v Spanned record format is not supported. v OPEN I-O and REWRITE are not supported. If you attempt one of these operations, one of the following file-status conditions results: 37 from OPEN I-O 47 from REWRITE (because you could not have successfully opened the file as I-O) Usage notes v File status 39 (fixed file attribute conflict) is not enforced for either of the following types of conflicts: Record-length conflict Record-type conflict (fixed as opposed to variable) v A READ returns the number of bytes of the maximum logical record size for the file except for the last record, which might be shorter. For example, suppose that a file definition has level-01 record descriptions of 3, 5, and 10 bytes long, and you write the following three records: abc, defgh, and ijklmnopqr, in that order. The first READ of this file returns abcdefghij, the second READ returns klmnopqr , and the third READ results in the AT END condition. For compatibility with releases of IBM COBOL before COBOL for OS/390 & VM Version 2 Release 2, you can also specify FILEDATA=TEXT when using a DD allocation for HFS files, but this use is not recommended. To process text files in the HFS, use LINE SEQUENTIAL organization. If you use QSAM to process text files in the HFS, you cannot use environment variables to define the files.
RELATED TASKS

Allocating files on page 149 Defining and allocating QSAM files on page 166 z/OS DFSMS: Using Data Sets (Using HFS data sets)

Labels for QSAM files


You can use labels to identify magnetic tape and direct access volumes and data sets. The operating system uses label-processing routines to identify and verify labels and locate volumes and data sets.

174

Enterprise COBOL for z/OS V4.2 Programming Guide

There are two kinds of labels: standard and nonstandard. Enterprise COBOL does not support nonstandard user labels. In addition, standard user labels contain user-specified information about the associated data set. Standard labels consist of volume labels and groups of data-set labels. Volume labels precede or follow data on the volume, and identify and describe the volume. The data-set labels precede or follow each data set on the volume, and identify and describe the data set. v The data-set labels that precede the data set are called header labels. v The data-set labels that follow the data set are called trailer labels. They are similar to the header labels, except that they also contain a count of blocks in the data set. v The data-set label groups can optionally include standard user labels. v The volume label groups can optionally include standard user labels.
RELATED TASKS

Using trailer and header labels


RELATED REFERENCES

Format of standard labels on page 176

Using trailer and header labels


You can create, examine, or update user labels when the beginning or end of a data set or volume (reel) is reached. End-of-volume or beginning-of-volume exits are allowed. You can also create or examine intermediate trailers and headers. You can create, examine, or update up to eight header labels and eight trailer labels on each volume of the data set. (QSAM EXTEND works in a manner identical to OUTPUT except that the beginning-of-file label is not processed.) Labels reside on the initial volume of a multivolume data set. This volume must be mounted as CLOSE if trailer labels are to be created, examined, or updated. Trailer labels for files opened as INPUT or I-O are processed when a CLOSE statement is performed for the file that has reached an AT END condition. If you code a header or trailer with the wrong position number, the result is unpredictable. (Data management might force the label to the correct relative position.) When you use standard label processing, code the label type of the standard and user labels (SUL) on the DD statement that describes the data set. Getting a user-label track: If you use a LABEL subparameter of SUL for direct access volumes, a separate user-label track is allocated when the data set is created. This additional track is allocated at initial allocation and for sequential data sets at end-of-volume (volume switch). The user-label track (one per volume of a sequential data set) contains both user header and user trailer labels. If a LABEL name is referenced outside the user LABEL declarative, results are unpredictable. Handling user labels: The USE AFTER LABEL declarative provides procedures for handling user labels on supported files. The AFTER option indicates processing of standard user labels. List the labels as data-names in the LABEL RECORDS clause in the FD entry for the file.
Chapter 9. Processing QSAM files

175

Table 22. Handling of QSAM user labels When the file is opened as: INPUT And: USE . . . LABEL declarative is coded for the OPEN option or for the file. USE . . . LABEL declarative is coded for the OPEN option or for the file. CLOSE statement is performed for the file that has reached the AT END condition. Result: The label is read and control is passed to the LABEL declarative. A buffer area for the label is provided, and control is passed to the LABEL declarative. Control is passed to the LABEL declarative for processing trailer labels.

OUTPUT

INPUT or I-O

You can specify a special exit by using the statement GO TO MORE-LABELS. When this statement results in an exit from a label DECLARATIVE SECTION, the system takes one of the following actions: v Writes the current beginning or ending label, and then reenters the USE section at its beginning to create more labels. After creating the last label, the system exits by performing the last statement of the section. v Reads an additional beginning or ending label, and then reenters the USE section at its beginning to check more labels. When processing user labels, the system reenters the section only if there is another user label to check. Hence, a program path that flows through the last statement in the section is not needed. If a GO TO MORE-LABELS statement is not performed for a user label, the DECLARATIVE SECTION is not reentered to check or create any immediately succeeding user labels.
RELATED CONCEPTS

Labels for QSAM files on page 174

Format of standard labels


Standard labels are 80-character records that are recorded in EBCDIC or ASCII. The first four characters are always used to identify the labels.
Table 23. Identifiers for standard tape labels Identifier VOL1 HDR1 or HDR2 EOV1 or EOV2 EOF1 or EOF2 UHL1 to UHL8 UTL1 to UTL8 Description Volume label Data set header labels Data set trailer labels (end-of-volume) Data set trailer labels (end-of-data-set) User header labels User trailer labels

The format of the label for a direct-access volume is the almost the same as the format of the label group for a tape volume label group. The difference is that a data-set label of the initial DASTO volume label consists of the data set control block (DSCB). The DSCB appears in the volume table of contents (VTOC) and contains the equivalent of the tape data set header and trailer, in addition to control information such as space allocation.

176

Enterprise COBOL for z/OS V4.2 Programming Guide

Standard user labels


User labels are optional within the standard label groups. The format for user header labels (UHL1-8) and user trailer labels (UTL1-8) consists of a label 80 characters in length recorded in either: v EBCDIC on DASD or on IBM standard labeled tapes v ASCII or ISO/ANSI labeled tapes The first 3 bytes consist of the characters that identify the label as either: v UHL for a user header label (at the beginning of a data set) v UTL for a user trailer label (at the end-of-volume or end-of-data set) The next byte contains the relative position of this label within a set of labels of the same type; one to eight labels are permitted. The remaining 76 bytes consist of user-specified information. Standard user labels are not supported for QSAM striped data sets.
RELATED CONCEPTS

Labels for QSAM files on page 174

Processing QSAM ASCII files on tape


If your program processes a QSAM ASCII file, you must request the ASCII alphabet, define the record formats, and define the ddname (with JCL). In addition, if your program processes signed numeric data items from ASCII files, define the numeric data as zoned decimal items with separate signs, that is, as USAGE DISPLAY and with the SEPARATE phrase of the SIGN clause. The CODEPAGE compiler option has no effect on the code page used for conversions between ASCII and EBCDIC for ASCII tape support. See the z/OS DFSMS documentation for information about how CCSIDs used for the ASCII tape support are selected and what the default CCSIDs are. Requesting the ASCII alphabet: In the SPECIAL-NAMES paragraph, code STANDARD-1 for ASCII:
ALPHABET-NAME IS STANDARD-1

In the FD entry for the file, code:


CODE-SET IS ALPHABET-NAME

Defining the record formats: Process QSAM ASCII tape files with any of these record formats: v Fixed length (format F) v Undefined (format U) v Variable length (format V) If you use variable-length records, you cannot explicitly code format D; instead, code RECORDING MODE V. The format information is internally converted to D mode. D-mode records have a 4-byte record descriptor for each record.

Chapter 9. Processing QSAM files

177

Defining the ddname: Under z/OS, processing ASCII files requires special JCL coding. Code these subparameters of the DCB parameter in the DD statement: BUFOFF=[L|n] L n A 4-byte block prefix that contains the block length (including the block prefix) The length of the block prefix: v For input, from 0 through 99 v For output, either 0 or 4 Use this value if you coded BLOCK CONTAINS 0. BLKSIZE=n n The size of the block, including the length of the block prefix

LABEL=[AL|AUL|NL] AL AUL NL OPTCD=Q Q This value is required for ASCII files and is the default if the file is created using Enterprise COBOL. American National Standard (ANS) labels ANS and user labels No labels

RELATED TASKS

Processing ASCII file labels


RELATED REFERENCES

z/OS DFSMS: Using Data Sets (Character data conversion)

Processing ASCII file labels


Standard label processing for ASCII files is the same as standard label processing for EBCDIC files. The system translates ASCII code into EBCDIC before processing. All ANS user labels are optional. ASCII files can have user header labels (UHLn) and user trailer labels (UTLn). There is no limit to the number of user labels at the beginning and the end of a file; you can write as many labels as you need. All user labels must be 80 bytes in length. To create or verify user labels (user label exit), code a USE AFTER STANDARD LABEL procedure. You cannot use USE BEFORE STANDARD LABEL procedures. ASCII files on tape can have: v ANS labels v ANS and user labels v No labels Any labels on an ASCII tape must be in ASCII code only. Tapes that contain a combination of ASCII and EBCDIC cannot be read.
RELATED TASKS

Processing QSAM ASCII files on tape on page 177

178

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 10. Processing VSAM files


Virtual storage access method (VSAM) is an access method for files on direct-access storage devices. With VSAM you can load files, retrieve records from files, update files, and add, replace, and delete records in files. VSAM processing has these advantages over QSAM: v Protection of data against unauthorized access v Compatibility across systems v Independence of devices (no need to be concerned with block size and other control information) v Simpler JCL (information needed by the system is provided in integrated catalogs) v Ability to use indexed file organization or relative file organization The table below shows how VSAM terms differ from COBOL terms and other terms that you might be familiar with.
Table 24. Comparison of VSAM, COBOL, and non-VSAM terminology VSAM term Data set Entry-sequenced data set (ESDS) Key-sequenced data set (KSDS) Relative-record data set (RRDS) Control interval Control interval size (CISZ) Buffers (BUFNI/BUFND) Access method control block (ACB) Cluster (CL) Cluster definition AMP parameter of JCL DD statement Record size COBOL term File Sequential file Indexed file Relative file Similar non-VSAM term Data set QSAM data set ISAM data set BDAM data set Block Block size BUFNO Data control block (DCB) Data set Data-set allocation DCB parameter of JCL DD statement Record length

The term file in this VSAM documentation refers to either a COBOL file or a VSAM data set. If you have complex requirements or frequently use VSAM, review the VSAM publications for your operating system.
RELATED CONCEPTS

VSAM files on page 180


RELATED TASKS

Defining VSAM file organization and records on page 181 Coding input and output statements for VSAM files on page 187 Handling errors in VSAM files on page 195 Protecting VSAM files with a password on page 196
Copyright IBM Corp. 1991, 2009

179

Working with VSAM data sets under z/OS and z/OS UNIX on page 197 Improving VSAM performance on page 203
RELATED REFERENCES

z/OS DFSMS: Using Data Sets z/OS DFSMS Macro Instructions for Data Sets z/OS DFSMS: Access Method Services for Catalogs

VSAM files
The physical organization of VSAM data sets differs considerably from the organizations used by other access methods. VSAM data sets are held in control intervals (CI) and control areas (CA). The size of the CI and CA is normally determined by the access method, and the way in which they are used is not visible to you. You can use three types of file organization with VSAM: VSAM sequential file organization (Also referred to as VSAM ESDS (entry-sequenced data set) organization.) In VSAM sequential file organization, the records are stored in the order in which they were entered. VSAM entry-sequenced data sets are equivalent to QSAM sequential files. The order of the records is fixed. VSAM indexed file organization (Also referred to as VSAM KSDS (key-sequenced data set) organization.) In a VSAM indexed file (KSDS), the records are ordered according to the collating sequence of an embedded prime key field, which you define. The prime key consists of one or more consecutive characters in the records. The prime key uniquely identifies the record and determines the sequence in which it is accessed with respect to other records. A prime key for a record might be, for example, an employee number or an invoice number. VSAM relative file organization (Also referred to as VSAM fixed-length or variable-length RRDS (relative-record data set) organization.) A VSAM relative-record data set (RRDS) contains records ordered by their relative key. The relative key is the relative record number, which represents the location of the record relative to where the file begins. The relative record number identifies the fixed- or variable-length record. In a VSAM fixed-length RRDS, records are placed in a series of fixed-length slots in storage. Each slot is associated with a relative record number. For example, in a fixed-length RRDS containing 10 slots, the first slot has a relative record number of 1, and the tenth slot has a relative record number of 10. In a VSAM variable-length RRDS, the records are ordered according to their relative record number. Records are stored and retrieved according to the relative record number that you set. Throughout this documentation, the term VSAM relative-record data set (or RRDS) is used to mean both relative-record data sets with fixed-length records and with variable-length records, unless they need to be differentiated.

180

Enterprise COBOL for z/OS V4.2 Programming Guide

The following table compares the characteristics of the different types of VSAM data sets.
Table 25. Comparison of VSAM data-set types Characteristic Order of records Access Alternate indexes Entry-sequenced data set (ESDS) Order in which they are written Sequential Can have one or more alternate indexes, although not supported in COBOL Key-sequenced data set (KSDS) Collating sequence by key field By key through an index Can have one or more alternate indexes RBA can change. Relative-record data set (RRDS) Order of relative record number By relative record number, which is handled like a key Cannot have alternate indexes

Relative byte address RBA cannot change. (RBA) and relative record number (RRN) of a record Space for adding records Uses space at the end of the data set

RRN cannot change.

Uses distributed free space for inserting records and changing their lengths in place

For fixed-length RRDS, uses empty slots in the data set For variable-length RRDS, uses distributed free space and changes the lengths of added records in place Space from a deleted record can be reused.

Space from deleting records

You cannot delete a record, but you can reuse its space for a record of the same length. Can have spanned records Can be reused unless it has an alternate index, is associated with key ranges, or exceeds 123 extents per volume

Space from a deleted or shortened record is automatically reclaimed in a control interval. Can have spanned records

Spanned records Reuse as work file

Cannot have spanned records

Can be reused Can be reused unless it has an alternate index, is associated with key ranges, or exceeds 123 extents per volume

RELATED TASKS

Specifying sequential organization for VSAM files on page 182 Specifying indexed organization for VSAM files on page 182 Specifying relative organization for VSAM files on page 184 Defining VSAM files on page 197

Defining VSAM file organization and records


Use an entry in the FILE-CONTROL paragraph in the ENVIRONMENT DIVISION to define the file organization and access modes for the VSAM files in your COBOL program. In the FILE SECTION of the DATA DIVISION, code a file description (FD) entry for the file. In the associated record description entry or entries, define the record-name and record length. Code the logical size of the records with the RECORD clause. Important: You can process VSAM data sets in Enterprise COBOL programs only after you define them with access method services.

Chapter 10. Processing VSAM files

181

Table 26. VSAM file organization, access mode, and record format File organization VSAM sequential (ESDS) VSAM indexed (KSDS) VSAM relative (RRDS) Sequential access Yes Yes Yes Random access No Yes Yes Dynamic access No Yes Yes Fixed length Yes Yes Yes Variable length Yes Yes Yes

RELATED TASKS

Specifying sequential organization for VSAM files Specifying indexed organization for VSAM files Specifying relative organization for VSAM files on page 184 Specifying access modes for VSAM files on page 185 Defining record lengths for VSAM files on page 185 Using file status keys on page 239 Using VSAM status codes (VSAM files only) on page 241 Defining VSAM files on page 197

Specifying sequential organization for VSAM files


Identify VSAM ESDS files in a COBOL program with the ORGANIZATION IS SEQUENTIAL clause. You can access (read or write) records in sequential files only sequentially. After you place a record in the file, you cannot shorten, lengthen, or delete it. However, you can update (REWRITE) a record if the length does not change. New records are added at the end of the file. The following example shows typical FILE-CONTROL entries for a VSAM sequential file (ESDS):
SELECT S-FILE ASSIGN TO SEQUENTIAL-AS-FILE ORGANIZATION IS SEQUENTIAL ACCESS IS SEQUENTIAL FILE STATUS IS FSTAT-CODE VSAM-CODE.
RELATED CONCEPTS

VSAM files on page 180

Specifying indexed organization for VSAM files


Identify a VSAM KSDS file in a COBOL program by using the ORGANIZATION IS INDEXED clause. Code a prime key for the record by using the RECORD KEY clause. You can also use alternate keys and an alternate index.
RECORD KEY IS data-name

In the example above, data-name is the name of the prime key field as you define it in the record description entry in the DATA DIVISION. The prime key data item can be class alphabetic, alphanumeric, DBCS, numeric, or national. If it has USAGE NATIONAL, the prime key can be category national, or can be a national-edited,

182

Enterprise COBOL for z/OS V4.2 Programming Guide

numeric-edited, national decimal, or national floating-point data item. The collation of record keys is based on the binary value of the keys regardless of the class or category of the keys. The following example shows the statements for a VSAM indexed file (KSDS) that is accessed dynamically. In addition to the primary key, COMMUTER-NO, an alternate key, LOCATION-NO, is specified:
SELECT I-FILE ASSIGN TO INDEXED-FILE ORGANIZATION IS INDEXED ACCESS IS DYNAMIC RECORD KEY IS IFILE-RECORD-KEY ALTERNATE RECORD KEY IS IFILE-ALTREC-KEY FILE STATUS IS FSTAT-CODE VSAM-CODE.
RELATED CONCEPTS

VSAM files on page 180


RELATED TASKS

Using alternate keys Using an alternate index


RELATED REFERENCES

RECORD KEY clause (Enterprise COBOL Language Reference) Classes and categories of data (Enterprise COBOL Language Reference)

Using alternate keys


In addition to the primary key, you can code one or more alternate keys for a VSAM KSDS file. By using alternate keys, you can access an indexed file to read records in some sequence other than the prime-key sequence. Alternate keys do not need to be unique. More than one record could be accessed if alternate keys are coded to allow duplicates. For example, you could access the file through employee department rather than through employee number. You define the alternate key in your COBOL program with the ALTERNATE RECORD KEY clause:
ALTERNATE RECORD KEY IS data-name

In the example above, data-name is the name of the alternate key field as you define it in the record description entry in the DATA DIVISION. Alternate key data items, like prime key data items, can be class alphabetic, alphanumeric, DBCS, numeric, or national. The collation of alternate keys is based on the binary value of the keys regardless of the class or category of the keys.

Using an alternate index


To use an alternate index for a VSAM KSDS file, you need to define a data set called the alternate index (AIX) by using access method services. The AIX contains one record for each value of a given alternate key. The records are in sequential order by alternate-key value. Each record contains the corresponding primary keys of all records in the associated indexed files that contain the alternate-key value.

Chapter 10. Processing VSAM files

183

RELATED TASKS

Creating alternate indexes on page 198

Specifying relative organization for VSAM files


Identify VSAM RRDS files in a COBOL program by using the ORGANIZATION IS RELATIVE clause. Use the RELATIVE KEY IS clause to associate each logical record with its relative record number. The following example shows a relative-record data set (RRDS) that is accessed randomly by the value in the relative key:
SELECT R-FILE ASSIGN TO RELATIVE-FILE ORGANIZATION IS RELATIVE ACCESS IS RANDOM RELATIVE KEY IS RFILE-RELATIVE-KEY FILE STATUS IS FSTAT-CODE VSAM-CODE.

You can use a randomizing routine to associate a key value in each record with the relative record number for that record. Although there are many techniques to convert a record key to a relative record number, the most commonly used is the division/remainder technique. With this technique, you divide the key by a value equal to the number of slots in the data set to produce a quotient and remainder. When you add one to the remainder, the result is a valid relative record number. Alternate indexes are not supported for VSAM RRDS.
RELATED CONCEPTS

VSAM files on page 180 Fixed-length and variable-length RRDS


RELATED TASKS

Using variable-length RRDS Defining VSAM files on page 197

Fixed-length and variable-length RRDS


In an RRDS that has fixed-length records, each record occupies one slot. You store and retrieve records according to the relative record number of the slot. A variable-length RRDS does not have slots; instead, the free space that you define allows for more efficient record insertions. When you load an RRDS that has fixed-length records, you have the option of skipping over slots and leaving them empty. When you load an RRDS that has variable-length records, you can skip over relative record numbers.

Using variable-length RRDS


To use relative-record data sets (RRDS) that have variable-length records, you must use VSAM variable-length RRDS support. Do these steps: 1. 2. 3. 4. Define the file with the ORGANIZATION IS RELATIVE clause. Use FD entries to describe the records with variable-length sizes. Use the NOSIMVRD runtime option. Define the VSAM file through access-method services as an RRDS.

184

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED TASKS

Defining VSAM files on page 197


RELATED REFERENCES

z/OS DFSMS: Access Method Services for Catalogs

Specifying access modes for VSAM files


You can access records in VSAM sequential files only sequentially. You can access records in VSAM indexed and relative files in three ways: sequentially, randomly, or dynamically. For sequential access, code ACCESS IS SEQUENTIAL in the FILE-CONTROL entry. Records in indexed files are then accessed in the order of the key field selected (either primary or alternate). Records in relative files are accessed in the order of the relative record numbers. For random access, code ACCESS IS RANDOM in the FILE-CONTROL entry. Records in indexed files are then accessed according to the value you place in a key field. Records in relative files are accessed according to the value you place in the relative key. For dynamic access, code ACCESS IS DYNAMIC in the FILE-CONTROL entry. Dynamic access is a mixed sequential-random access in the same program. Using dynamic access, you can write one program to perform both sequential and random processing, accessing some records in sequential order and others by their keys. Example: using dynamic access with VSAM files
RELATED TASKS

Reading records from a VSAM file on page 192

Example: using dynamic access with VSAM files


Suppose that you have an indexed file of employee records, and the employees hourly wage forms the record key. If your program processes those employees who earn between $15.00 and $20.00 per hour and those who earn $25.00 per hour and above, using dynamic access of VSAM files, the program would: 1. Retrieve the first record randomly (with a random-retrieval READ) based on the key of 1500. 2. Read sequentially (using READ NEXT) until the salary field exceeds 2000. 3. Retrieve the next record randomly, based on a key of 2500. 4. Read sequentially until the end of the file.
RELATED TASKS

Reading records from a VSAM file on page 192

Defining record lengths for VSAM files


You can define VSAM records to be fixed or variable in length. COBOL determines the record format from the RECORD clause and the record descriptions that are associated with the FD entry for a file.
Chapter 10. Processing VSAM files

185

Because the concept of blocking has no meaning for VSAM files, you can omit the BLOCK CONTAINS clause. The clause is syntax-checked, but it has no effect on how the program runs.
RELATED TASKS

Defining fixed-length records Defining variable-length records Enterprise COBOL Compiler and Runtime Migration Guide
RELATED REFERENCES

FILE SECTION entries on page 14

Defining fixed-length records


To define VSAM records as fixed length, use one of these coding options.
Table 27. Definition of VSAM fixed-length records RECORD clause Code RECORD CONTAINS integer. Clause format 1 Record length Fixed in size with a length of integer-3 bytes Comments The lengths of the level-01 record description entries associated with the file do not matter.

Omit the RECORD clause, but code all level-01 records that are associated with the file as the same size; and code none with an OCCURS DEPENDING ON clause.

The fixed size that you coded

RELATED REFERENCES

RECORD clause (Enterprise COBOL Language Reference)

Defining variable-length records


To define VSAM records as variable length, use one of these coding options.
Table 28. Definition of VSAM variable-length records RECORD clause Clause format Maximum record length integer-7 bytes Comments The lengths of the level-01 record description entries associated with the file do not matter.

Code RECORD IS VARYING 3 FROM integer-6 TO integer-7.

Code RECORD IS VARYING.

Size of the largest level-01 The compiler determines record description entry the maximum record associated with the file length. integer-5 bytes The minimum record length is integer-4 bytes.

Code RECORD CONTAINS integer-4 TO integer-5.

186

Enterprise COBOL for z/OS V4.2 Programming Guide

Table 28. Definition of VSAM variable-length records (continued) RECORD clause Omit the RECORD clause, but code multiple level-01 records that are associated with the file and are of different sizes or contain an OCCURS DEPENDING ON clause. Clause format Maximum record length Comments

Size of the largest level-01 The compiler determines record description entry the maximum record associated with the file length.

When you specify a READ INTO statement for a format-V file, the record size that is read for that file is used in the MOVE statement generated by the compiler. Consequently, you might not get the result you expect if the record read in does not correspond to the level-01 record description. All other rules of the MOVE statement apply. For example, when you specify a MOVE statement for a format-V record read in by the READ statement, the size of the record corresponds to its level-01 record description.
RELATED REFERENCES

RECORD clause (Enterprise COBOL Language Reference)

Coding input and output statements for VSAM files


Use the COBOL statements shown below to process VSAM files. OPEN WRITE START To connect the VSAM data set to your COBOL program for processing. To add records to a file or load a file. To establish the current location in the cluster for a READ NEXT statement. START does not retrieve a record; it only sets the current record pointer. READ and READ NEXT To retrieve records from a file. REWRITE To update records. DELETE To logically remove records from indexed and relative files only. CLOSE To disconnect the VSAM data set from your program.

All of the following factors determine which input and output statements you can use for a given VSAM data set: v Access mode (sequential, random, or dynamic) v File organization (ESDS, KSDS, or RRDS) v Mode of OPEN statement (INPUT, OUTPUT, I-O, or EXTEND) The following table shows the possible combinations of statements and open modes for sequential files (ESDS). The X indicates that you can use a statement with the open mode shown at the top of the column.

Chapter 10. Processing VSAM files

187

Table 29. I/O statements for VSAM sequential files Access mode Sequential COBOL statement OPEN WRITE START READ REWRITE DELETE CLOSE X X X X X X X OPEN INPUT X OPEN OUTPUT X X OPEN I-O X OPEN EXTEND X X

The following table shows the possible combinations of statements and open modes you can use with indexed (KSDS) files and relative (RRDS) files. The X indicates that you can use the statement with the open mode shown at the top of the column.
Table 30. I/O statements for VSAM relative and indexed files Access mode Sequential COBOL statement OPEN WRITE START READ REWRITE DELETE CLOSE Random OPEN WRITE START READ REWRITE DELETE CLOSE Dynamic OPEN WRITE START READ REWRITE DELETE CLOSE X X X X X X X X X X X X X X X X X X X X X X X X X X X X OPEN INPUT X OPEN OUTPUT X X X X X X X X X X OPEN I-O X OPEN EXTEND X X

The fields that you code in the FILE STATUS clause are updated by VSAM after each input-output statement to indicate the success or failure of the operation.

188

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED CONCEPTS

File position indicator


RELATED TASKS

Opening a file (ESDS, KSDS, or RRDS) Reading records from a VSAM file on page 192 Updating records in a VSAM file on page 193 Adding records to a VSAM file on page 193 Replacing records in a VSAM file on page 194 Deleting records from a VSAM file on page 194 Closing VSAM files on page 194
RELATED REFERENCES

File status key (Enterprise COBOL Language Reference)

File position indicator


The file position indicator marks the next record to be accessed for sequential COBOL requests. You do not set the file position indicator in your program. It is set by successful OPEN, START, READ, and READ NEXT statements. Subsequent READ or READ NEXT requests use the established file position indicator location and update it. The file position indicator is not used or affected by the output statements WRITE, REWRITE, or DELETE. The file position indicator has no meaning for random processing.
RELATED TASKS

Reading records from a VSAM file on page 192

Opening a file (ESDS, KSDS, or RRDS)


Before you can use WRITE, START, READ, REWRITE, or DELETE statements to process records in a file, you must first open the file with an OPEN statement. File availability and creation affect OPEN processing, optional files, and file status codes 05 and 35. For example, if you open a file that is neither optional nor available in EXTEND, I-O, or INPUT mode, you get file status 35 and the OPEN statement fails. If the file is OPTIONAL, the same OPEN statement creates the file and returns file status 05. An OPEN operation works successfully only when you set fixed file attributes in the DD statement or data-set label for a file and specify consistent attributes for the file in the SELECT clause and FD entries of your COBOL program. Mismatches in the following items result in a file status code 39 and the failure of the OPEN statement: v Attributes for file organization (sequential, relative, or indexed) v Prime record key v Alternate record keys v Maximum record size v Record type (fixed or variable) How you code the OPEN statement for a VSAM file depends on whether the file is empty (a file that has never contained records) or loaded. For either type of file, your program should check the file status key after each OPEN statement.
Chapter 10. Processing VSAM files

189

RELATED TASKS

Opening an empty file Opening a loaded file (a file with records) on page 191
RELATED REFERENCES

Statements to load records into a VSAM file on page 191

Opening an empty file


To open a file that has never contained records (an empty file), use a form of the OPEN statement. Depending on the type of file that you are opening, use one of the following statements: v OPEN OUTPUT for ESDS files. v OPEN OUTPUT or OPEN EXTEND for KSDS and RRDS files. (Either coding has the same effect.) If you coded the file for random or dynamic access and the file is optional, you can use OPEN I-O. Optional files are files that are not necessarily available each time a program is run. You can define files opened in INPUT, I-O, or OUTPUT mode as optional by defining them with the SELECT OPTIONAL clause in the FILE-CONTROL paragraph. Initially loading a file sequentially: Initially loading a file means writing records into the file for the first time. Doing so is not the same as writing records into a file from which all previous records have been deleted. To initially load a VSAM file: 1. Open the file. 2. Use sequential processing (ACCESS IS SEQUENTIAL). (Sequential processing is faster than random or dynamic processing.) 3. Use WRITE to add a record to the file. Using OPEN OUTPUT to load a VSAM file significantly improves the performance of your program. Using OPEN I-O or OPEN EXTEND has a negative effect on the performance of your program. When you load VSAM indexed files sequentially, you optimize both loading performance and subsequent processing performance, because sequential processing maintains user-defined free space. Future insertions will be more efficient. With ACCESS IS SEQUENTIAL, you must write the records in ascending RECORD KEY order. When you load VSAM relative files sequentially, the records are placed in the file in the ascending order of relative record numbers. Initially loading a file randomly or dynamically: You can use random or dynamic processing to load a file, but they are not as efficient as sequential processing. Because VSAM does not support random or dynamic processing, COBOL has to perform some extra processing to enable you to use ACCESS IS RANDOM or ACCESS IS DYNAMIC with OPEN OUTPUT or OPEN I-O. These steps prepare the file for use and give it the status of a loaded file because it has been used at least once.

190

Enterprise COBOL for z/OS V4.2 Programming Guide

In addition to extra overhead for preparing files for use, random processing does not consider any user-defined free space. As a result, any future insertions might be inefficient. Sequential processing maintains user-defined free space. When you are loading an extended-format VSAM data set, file status 30 will occur for the OPEN if z/OS DFSMS system-managed buffering sets the buffering to local shared resources (LSR). To successfully load the VSAM data set in this case, specify ACCBIAS=USER in the DD AMP parameter for the VSAM data set to bypass system-managed buffering. Loading a VSAM data set with access method services: You can load or update a VSAM data set by using the access method services REPRO command. Use REPRO whenever possible.
RELATED TASKS

Opening a loaded file (a file with records)


RELATED REFERENCES

Statements to load records into a VSAM file z/OS DFSMS: Access Method Services for Catalogs (REPRO)

Statements to load records into a VSAM file


Use the statements shown below to load records into a VSAM file.
Table 31. Statements to load records into a VSAM file Division ENVIRONMENT DIVISION ESDS SELECT ASSIGN FILE STATUS PASSWORD ACCESS MODE KSDS SELECT ASSIGN ORGANIZATION IS INDEXED RECORD KEY ALTERNATE RECORD KEY FILE STATUS PASSWORD ACCESS MODE FD entry OPEN OUTPUT OPEN EXTEND WRITE CLOSE RRDS SELECT ASSIGN ORGANIZATION IS RELATIVE RELATIVE KEY FILE STATUS PASSWORD ACCESS MODE FD entry OPEN OUTPUT OPEN EXTEND WRITE CLOSE

DATA DIVISION PROCEDURE DIVISION

FD entry OPEN OUTPUT OPEN EXTEND WRITE CLOSE

RELATED TASKS

Opening an empty file on page 190 Updating records in a VSAM file on page 193

Opening a loaded file (a file with records)


To open a file that already contains records, use OPEN INPUT, OPEN I-O, or OPEN EXTEND. If you open a VSAM entry-sequenced or relative-record file as EXTEND, the added records are placed after the last existing records in the file. If you open a VSAM key-sequenced file as EXTEND, each record you add must have a record key higher than the highest record in the file.
Chapter 10. Processing VSAM files

191

RELATED TASKS

Opening an empty file on page 190 Working with VSAM data sets under z/OS and z/OS UNIX on page 197
RELATED REFERENCES

Statements to load records into a VSAM file on page 191 z/OS DFSMS: Access Method Services for Catalogs

Reading records from a VSAM file


Use the READ statement to retrieve (READ) records from a file. To read a record, you must have opened the file INPUT or I-O. Your program should check the file status key after each READ. You can retrieve records in VSAM sequential files only in the sequence in which they were written. You can retrieve records in VSAM indexed and relative record files in any of the following ways: Sequentially According to the ascending order of the key you are using, the RECORD KEY or the ALTERNATE RECORD KEY, beginning at the current position of the file position indicator for indexed files, or according to ascending relative record locations for relative files Randomly In any order, depending on how you set the RECORD KEY or ALTERNATE RECORD KEY or the RELATIVE KEY before your READ request Dynamically Mixed sequential and random With dynamic access, you can switch between reading a specific record directly and reading records sequentially, by using READ NEXT for sequential retrieval and READ for random retrieval (by key). When you want to read sequentially, beginning at a specific record, use START before the READ NEXT statement to set the file position indicator to point to a particular record. When you code START followed by READ NEXT, the next record is read and the file position indicator is reset to the next record. You can move the file position indicator randomly by using START, but all reading is done sequentially from that point.
START file-name KEY IS EQUAL TO ALTERNATE-RECORD-KEY

When a direct READ is performed for a VSAM indexed file, based on an alternate index for which duplicates exist, only the first record in the data set (base cluster) with that alternate key value is retrieved. You need a series of READ NEXT statements to retrieve each of the data set records with the same alternate key. A file status code of 02 is returned if there are more records with the same alternate key value to be read; a code of 00 is returned when the last record with that key value has been read.
RELATED CONCEPTS

File position indicator on page 189

192

Enterprise COBOL for z/OS V4.2 Programming Guide

RELATED TASKS

Specifying access modes for VSAM files on page 185

Updating records in a VSAM file


To update a VSAM file, use these PROCEDURE DIVISION statements.
Table 32. Statements to update records in a VSAM file Access method ACCESS IS SEQUENTIAL ESDS OPEN EXTEND WRITE CLOSE or OPEN I-O READ REWRITE CLOSE ACCESS IS RANDOM Not applicable KSDS OPEN EXTEND WRITE CLOSE or OPEN I-O READ REWRITE DELETE CLOSE OPEN I-O READ WRITE REWRITE DELETE CLOSE OPEN I-O READ NEXT WRITE REWRITE START DELETE CLOSE OPEN I-O READ WRITE REWRITE DELETE CLOSE RRDS OPEN EXTEND WRITE CLOSE or OPEN I-O READ REWRITE DELETE CLOSE OPEN I-O READ WRITE REWRITE DELETE CLOSE OPEN I-O READ NEXT WRITE REWRITE START DELETE CLOSE OPEN I-O READ WRITE REWRITE DELETE CLOSE

ACCESS IS DYNAMIC (sequential processing)

Not applicable

ACCESS IS DYNAMIC (random processing)

Not applicable

RELATED REFERENCES

Statements to load records into a VSAM file on page 191

Adding records to a VSAM file


Use the COBOL WRITE statement to add a record to a file without replacing any existing records. The record to be added must not be larger than the maximum record size that you set when you defined the file. Your program should check the file status key after each WRITE statement. Adding records sequentially: Use ACCESS IS SEQUENTIAL and code the WRITE statement to add records sequentially to the end of a VSAM file that has been opened with either OUTPUT or EXTEND.

Chapter 10. Processing VSAM files

193

Sequential files are always written sequentially. For indexed files, you must write new records in ascending key sequence. If you open the file EXTEND, the record keys of the records to be added must be higher than the highest primary record key on the file when you opened the file. For relative files, the records must be in sequence. If you include a RELATIVE KEY data item in the SELECT clause, the relative record number of the record to be written is placed in that data item. Adding records randomly or dynamically: When you write records to an indexed data set and ACCESS IS RANDOM or ACCESS IS DYNAMIC, you can write the records in any order.

Replacing records in a VSAM file


To replace a record in a VSAM file, use REWRITE on a file that you opened as I-O. If the file was not opened as I-O, the record is not rewritten and the status key is set to 49. Check the file status key after each REWRITE statement. For sequential files, the length of the replacement record must be the same as the length of the original record. For indexed files or variable-length relative files, you can change the length of the record you replace. To replace a record randomly or dynamically, you do not have to first READ the record. Instead, locate the record you want to replace as follows: v For indexed files, move the record key to the RECORD KEY data item, and then issue the REWRITE. v For relative files, move the relative record number to the RELATIVE KEY data item, and then issue the REWRITE.

Deleting records from a VSAM file


To remove an existing record from an indexed or relative file, open the file I-O and use the DELETE statement. You cannot use DELETE on a sequential file. When you use ACCESS IS SEQUENTIAL or the file contains spanned records, your program must first read the record to be deleted. The DELETE then removes the record that was read. If the DELETE is not preceded by a successful READ, the deletion is not done and the status key value is set to 92. When you use ACCESS IS RANDOM or ACCESS IS DYNAMIC, your program does not have to first read the record to be deleted. To delete a record, move the key of the record to be deleted to the RECORD KEY data item, and then issue the DELETE. Your program should check the file status key after each DELETE statement.

Closing VSAM files


Use the CLOSE statement to disconnect your program from a VSAM file. If you try to close a file that is already closed, you will get a logic error. Check the file status key after each CLOSE statement.

194

Enterprise COBOL for z/OS V4.2 Programming Guide

If you do not close a VSAM file, the file is automatically closed for you under the following conditions, except for files defined in any OS/VS COBOL programs in the run unit: v When the run unit ends normally, all open files defined in any COBOL programs in the run unit are closed. v When the run unit ends abnormally, if the TRAP(ON) runtime option has been set, all open files defined in any COBOL programs in the run unit are closed. v When Language Environment condition handling has completed and the application resumes in a routine other than where the condition occurred, open files defined in any COBOL programs in the run unit that might be called again and reentered are closed. You can change the location where a program resumes after a condition is handled. To make this change, you can, for example, move the resume cursor with the CEEMRCR callable service or use language constructs such as a C longjmp statement. v When you issue CANCEL for a COBOL subprogram, any open nonexternal files defined in that program are closed. v When a COBOL subprogram with the INITIAL attribute returns control, any open nonexternal files defined in that program are closed. v When a thread of a multithreaded application ends, both external and nonexternal files that were opened from within that same thread are closed. File status key data items in the DATA DIVISION are set when these implicit CLOSE operations are performed, but your EXCEPTION/ERROR and LABEL declaratives are not invoked. Errors: If you open a VSAM file in a multithreaded application, you must close it from the same thread of execution. Attempting to close the file from a different thread results in a close failure with file-status condition 90.

Handling errors in VSAM files


When an input or output statement operation fails, COBOL does not perform corrective action for you. All OPEN and CLOSE errors with a VSAM file, whether logical errors in your program or input/output errors on the external storage media, return control to your COBOL program even if you coded no DECLARATIVE and no FILE STATUS clause. If any other input or output statement operation fails, you choose whether your program will continue running after a less-than-severe error. COBOL provides these ways for you to intercept and handle certain VSAM input and output errors: v End-of-file phrase (AT END) v EXCEPTION/ERROR declarative v FILE STATUS clause (file status key and VSAM status code) v INVALID KEY phrase You should define a status key for each VSAM file that you define in your program. Check the status key value after each input or output request, especially OPEN and CLOSE.
Chapter 10. Processing VSAM files

195

If you do not code a file status key or a declarative, serious VSAM processing errors will cause a message to be issued and a Language Environment condition to be signaled, which will cause an abend if you specify the runtime option ABTERMENC(ABEND).
RELATED TASKS

Handling errors in input and output operations on page 235 Using VSAM status codes (VSAM files only) on page 241
RELATED REFERENCES

z/OS DFSMS Macro Instructions for Data Sets (VSAM macro return and reason codes)

Protecting VSAM files with a password


Although the preferred security mechanism on a z/OS system is RACF, Enterprise COBOL also supports using explicit passwords on VSAM files to prevent unauthorized access and update. To use explicit passwords, code the PASSWORD clause in the FILE-CONTROL paragraph. Use this clause only if the catalog entry for the files includes a read or an update password: v If the catalog entry includes a read password, you cannot open and access the file in a COBOL program unless you use the PASSWORD clause in the FILE-CONTROL paragraph and describe it in the DATA DIVISION. The data-name referred to must contain a valid password when the file is opened. v If the catalog entry includes an update password, you can open and access it, but not update it, unless you code the PASSWORD clause in the FILE-CONTROL paragraph and describe it in the DATA DIVISION. v If the catalog entry includes both a read password and an update password, specify the update password to both read and update the file in your program. If your program only retrieves records and does not update them, you need only the read password. If your program loads files or updates them, you need to specify the update password that was cataloged. For indexed files, the PASSWORD data item for the RECORD KEY must contain the valid password before the file can be successfully opened. If you password-protect a VSAM indexed file, you must also password-protect each alternate index in order to be fully password protected. Where you place the PASSWORD clause is important because each alternate index has its own password. The PASSWORD clause must directly follow the key clause to which it applies.

Example: password protection for a VSAM indexed file


The following example shows the COBOL code used for a VSAM indexed file that has password protection.
. . . INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT LIBFILE ASSIGN TO PAYMAST ORGANIZATION IS INDEXED RECORD KEY IS EMPL-NUM

196

Enterprise COBOL for z/OS V4.2 Programming Guide

PASSWORD IS BASE-PASS ALTERNATE RECORD KEY IS EMPL-PHONE PASSWORD IS PATH1-PASS . . . WORKING-STORAGE SECTION. 01 BASE-PASS PIC X(8) VALUE "25BSREAD". 01 PATH1-PASS PIC X(8) VALUE "25ATREAD".

Working with VSAM data sets under z/OS and z/OS UNIX
Be aware of special coding considerations for VSAM files under z/OS and z/OS UNIX for access method services (IDCAMS) commands, environment variables, and JCL. A VSAM file is available if all of the following conditions are true: v You define it using access method services. v You define it for your program by providing a DD statement, an environment variable, or an ALLOCATE command. v It has previously contained a record. A VSAM file is unavailable if it has never contained a record, even if you have defined the file. You always get a return code of zero on completion of the OPEN statement for a VSAM sequential file. Use the access method services REPRO command to empty a file. Deleting records in this manner resets the high-use relative byte address (RBA) of the file to zero. The file is effectively empty and appears to COBOL as if it never contained a record.
RELATED TASKS

Defining files to the operating system on page 10 Defining VSAM files Creating alternate indexes on page 198 Allocating VSAM files on page 200 Sharing VSAM files through RLS on page 202

Defining VSAM files


You can process VSAM entry-sequenced, key-sequenced, and relative-record data sets in Enterprise COBOL only after you define them through access method services (IDCAMS). A VSAM cluster is a logical definition for a VSAM data set and has one or two components: v The data component of a VSAM cluster contains the data records. v The index component of a VSAM key-sequenced cluster consists of the index records. Use the DEFINE CLUSTER access-method services command to define VSAM data sets (clusters). This process includes creating an entry in an integrated catalog without any data transfer. Define the following information about the cluster: v Name of the entry

Chapter 10. Processing VSAM files

197

v Name of the catalog to contain this definition and its password (can use default name) v Organization (sequential, indexed, or relative) v Device and volumes that the data set will occupy v Space required for the data set v Record size and control interval sizes (CISIZE) v Passwords (if any) required for future access Depending on what kind of data set is in the cluster, also define the following information for each cluster: v For VSAM indexed data sets (KSDS), specify length and position of the prime key in the records. v For VSAM fixed-length relative-record data sets (RRDS), specify the record size as greater than or equal to the maximum size COBOL record:
DEFINE CLUSTER NUMBERED RECORDSIZE(n,n)

When you define a data set in this way, all records are padded to the fixed slot size n. If you use the RECORD IS VARYING ON data-name form of the RECORD clause, a WRITE or REWRITE uses the length specified in DEPENDING ON data-name as the length of the record to be transferred by VSAM. This data is then padded to the fixed slot size. READ statements always return the fixed slot size in the DEPENDING ON data-name. v For VSAM variable-length relative-record data sets (RRDS), specify the average size COBOL record expected and the maximum size COBOL record expected:
DEFINE CLUSTER NUMBERED RECORDSIZE(avg,m)

The average size COBOL record expected must be less than the maximum size COBOL record expected.
RELATED TASKS

Creating alternate indexes Allocating VSAM files on page 200 Specifying relative organization for VSAM files on page 184
RELATED REFERENCES

z/OS DFSMS: Access Method Services for Catalogs

Creating alternate indexes


An alternate index provides access to the records in a data set that uses more than one key. It accesses records in the same way as the prime index key of an indexed data set (KSDS). When planning to use an alternate index, you must know: v The type of data set (base cluster) with which the index will be associated v Whether the keys will be unique or not unique v Whether the index is to be password protected v Some of the performance aspects of using alternate indexes Because an alternate index is, in practice, a VSAM data set that contains pointers to the keys of a VSAM data set, you must define the alternate index and the alternate index path (the entity that establishes the relationship between the alternate index

198

Enterprise COBOL for z/OS V4.2 Programming Guide

and the prime index). After you define an alternate index, make a catalog entry to establish the relationship (or path) between the alternate index and its base cluster. This path allows you to access the records of the base cluster through the alternate keys. To use an alternate index, do these steps: 1. Define the alternate index by using the DEFINE ALTERNATEINDEX command. In it, specify these items: v Name of the alternate index v v v v Name of its related VSAM indexed data set Location in the record of any alternate indexes and whether they are unique Whether alternate indexes are to be updated when the data set is changed Name of the catalog to contain this definition and its password (can use default name)

In your COBOL program, the alternate index is identified solely by the ALTERNATE RECORD KEY clause in the FILE-CONTROL paragraph. The ALTERNATE RECORD KEY definitions must match the definitions in the catalog entry. Any password entries that you cataloged should be coded directly after the ALTERNATE RECORD KEY phrase. 2. Relate the alternate index to the base cluster (the data set to which the alternate index gives you access) by using the DEFINE PATH command. In it, specify these items: v Name of the path v Alternate index to which the path is related v Name of the catalog that contains the alternate index The base cluster and alternate index are described by entries in the same catalog. 3. Load the VSAM indexed data set. 4. Build the alternate index by using (typically) the BLDINDEX command. Identify the input file as the indexed data set (base cluster) and the output file as the alternate index or its path. BLDINDEX reads all the records in the VSAM indexed data set (or base cluster) and extracts the data needed to build the alternate index. Alternatively, you can use the runtime option AIXBLD to build the alternate index at run time. However, this option might adversely affect performance. Example: entries for alternate indexes
RELATED TASKS

Using an alternate index on page 183


RELATED REFERENCES

Language Environment Programming Reference (AIXBLD (COBOL only))

Example: entries for alternate indexes


The following example maps the relationships between the COBOL FILE-CONTROL entry and the DD statements or environment variables for a VSAM indexed file that has two alternate indexes. Using JCL:

Chapter 10. Processing VSAM files

199

//MASTERA //MASTERA1 //MASTERA2

DD DD DD

DSNAME=clustername,DISP=OLD DSNAME=path1,DISP=OLD DSNAME=path2,DISP=OLD

(1) (2) (3)

Using environment variables:


export MASTERA=DSN(clustername),OLD export MASTERA=DSN(path1),OLD export MASTERA=DSN(path2),OLD . . . FILE-CONTROL. SELECT MASTER-FILE ASSIGN TO MASTERA RECORD KEY IS EM-NAME PASSWORD IS PW-BASE ALTERNATE RECORD KEY IS EM-PHONE PASSWORD IS PW-PATH1 ALTERNATE RECORD KEY IS EM-CITY PASSWORD IS PW-PATH2. (1) (2) (3) (4) (5) (6) (7)

(1) (2) (3) (4) (5) (6) (7)

The base cluster name is clustername. The name of the first alternate index path is path1. The name of the second alternate index path is path2. The ddname or environment variable name for the base cluster is specified with the ASSIGN clause. Passwords immediately follow their indexes. The key EM-PHONE relates to the first alternate index. The key EM-CITY relates to the second alternate index.

RELATED TASKS

Creating alternate indexes on page 198

Allocating VSAM files


You must predefine and catalog all VSAM data sets through the access method services DEFINE command. Most of the information about a VSAM data set is in the catalog, so you need to specify only minimal DD or environment variable information. Allocation of VSAM files (indexed, relative, and sequential) follows the general rules for the allocation of COBOL files. When you use an environment variable to allocate a VSAM file, the variable name must be in uppercase. Usually the input and data buffers are the only variables that you are concerned about. You must specify these options in the order shown, but no others: 1. DSN(dsname), where dsname is the name of the base cluster 2. OLD or SHR The basic DD statement that you need for VSAM files and the corresponding export command are these:
//ddname DD DSN=dsname,DISP=SHR,AMP=AMORG export evname="DSN(dsname),SHR"

200

Enterprise COBOL for z/OS V4.2 Programming Guide

In either case, dsname must be the same as the name used in the access method services DEFINE CLUSTER or DEFINE PATH command. DISP must be OLD or SHR because the data set is already cataloged. If you specify MOD when using JCL, the data set is treated as OLD. AMP is a VSAM JCL parameter that supplements the information that the program supplies about the data set. AMP takes effect when your program opens the VSAM file. Any information that you set through the AMP parameter takes precedence over the information that is in the catalog or that the program supplies. The AMP parameter is required only under the following circumstances: v You use a dummy VSAM data set. For example,
//ddname DD //ddname // DD DUMMY,AMP=AMORG DSN=VSAM.dsname,DISP=SHR, AMP=('BUFNI=4,BUFND=8')

v You request additional index or data buffers. For example,

You cannot specify AMP if you allocate a VSAM data set with an environment variable. For a VSAM base cluster, specify the same system-name (ddname or environment variable name) that you specify in the ASSIGN clause after the SELECT clause. When you use alternate indexes in your COBOL program, you must specify not only a system-name (using a DD statement or environment variable) for the base cluster, but also a system-name for each alternate index path. No language mechanism exists to explicitly declare system-names for alternate index paths within the program. Therefore, you must adhere to the following guidelines for forming the system-name (ddname or environment variable name) for each alternate index path: v Concatenate the base cluster name with an integer. v Begin with 1 for the path associated with the first alternate record defined for the file in your program (ALTERNATE RECORD KEY clause of the FILE-CONTROL paragraph). v Increment by 1 for the path associated with each successive alternate record definition for that file. For example, if the system-name of a base cluster is ABCD, the system-name for the first alternate index path defined for the file in your program is ABCD1, the system-name for the second alternate index path is ABCD2, and so on. If the length of the base cluster system-name together with the sequence number exceeds eight characters, the base cluster portion of the system-name is truncated on the right to reduce the concatenated result to eight characters. For example, if the system-name of a base cluster is ABCDEFGH, the system name of the first alternate index path is ABCDEFG1, the tenth is ABCDEF10, and so on.
RELATED TASKS

Allocating files on page 149


RELATED REFERENCES

MVS Program Management: Users Guide and Reference

Chapter 10. Processing VSAM files

201

Sharing VSAM files through RLS


By using the VSAM JCL parameter RLS, you can specify record-level sharing with VSAM. Specifying RLS is the only way to request the RLS mode when running COBOL programs. Use RLS=CR when consistent read protocols are required, and RLS=NRI when no read integrity protocols are required. You cannot specify RLS if you allocate your VSAM data set with an environment variable
RELATED TASKS

Preventing update problems with VSAM files in RLS mode Handling errors in VSAM files in RLS mode on page 203
RELATED REFERENCES

Restrictions when using RLS on page 203

Preventing update problems with VSAM files in RLS mode


When you open a VSAM data set in RLS mode for I-O (updates), the first READ causes an exclusive lock of the record regardless of the value of RLS (RLS=CR or RLS=NRI) that you specify. If the COBOL file is defined as ACCESS RANDOM, VSAM releases the exclusive lock on the record after a WRITE or REWRITE statement is issued or a READ statement is issued for another record. When a WRITE or REWRITE is done, VSAM writes the record immediately. However, if the COBOL file is defined as ACCESS DYNAMIC, VSAM does not release the exclusive lock on the record after a WRITE or REWRITE statement, nor after a READ statement, unless the I-O statement causes VSAM to move to another control interval (CI). As a result, if a WRITE or REWRITE was done, VSAM does not write the record until processing is moved to another CI and the lock is released. When you use ACCESS DYNAMIC, one way to cause the record to be written immediately, to release the exclusive lock immediately, or both, is to define the VSAM data set to allow only one record per CI. Specifying RLS=CR locks a record and prevents an update to it until another READ is requested for another record. While a lock on the record being read is in effect, other users can request a READ for the same record, but they cannot update the record until the read lock is released. When you specify RLS=NRI, no lock will be in effect when a READ for input is issued. Another user might update the record. The locking rules for RLS=CR can cause the application to wait for availability of a record lock. This wait might slow down the READ for input. You might need to modify your application logic to use RLS=CR. Do not use the RLS parameter for batch jobs that update nonrecoverable spheres until you are sure that the application functions correctly in a multiple-updater environment. When you open a VSAM data set in RLS mode for INPUT or I-O processing, it is good to issue an OPEN or START immediately before a READ. If there is a delay between the OPEN or START and the READ, another user might add records before the record on which the application is positioned after the OPEN or START. The COBOL run time points explicitly to the beginning of the VSAM data set at the time when OPEN was requested, but another user might add records that would alter the true beginning of the VSAM data set if the READ is delayed.

202

Enterprise COBOL for z/OS V4.2 Programming Guide

Restrictions when using RLS


When you use RLS mode, several restrictions apply to VSAM cluster attributes and to runtime options. Be aware of these restrictions: v The VSAM cluster attributes KEYRANGE and IMBED are not supported when you open a VSAM file. v The VSAM cluster attribute REPLICATE is not recommended because the benefits are negated by the system-wide buffer pool and potentially large CF cache structure in the storage hierarchy. v The AIXBLD runtime option is not supported when you open a VSAM file because VSAM does not allow an empty path to be opened. If you need the AIXBLD runtime option to build the alternate index data set, open the VSAM data set in non-RLS mode. v The SIMVRD runtime option is not supported for VSAM files. v Temporary data sets are not allowed.

Handling errors in VSAM files in RLS mode


If your application accesses a VSAM data set in RLS mode, be sure to check the file status and VSAM feedback codes after each request. If your application encounters SMSVSAM server not available while processing input or output, explicitly close the VSAM file before you try to open it again. VSAM generates return code 16 for such failures, and there is no feedback code. You can have COBOL programs check the first 2 bytes of the second file status area for VSAM return code 16. The COBOL run time generates message IGZ0205W and automatically closes the file if the error occurs during OPEN processing. All other RLS mode errors return a VSAM return code of 4, 8, or 12.
RELATED TASKS

Using VSAM status codes (VSAM files only) on page 241

Improving VSAM performance


Your system programmer is most likely responsible for tuning the performance of COBOL and VSAM. As an application programmer, you can control the aspects of VSAM that are listed below.
Table 33. Methods for improving VSAM performance Aspect of VSAM What you can do Invoking access methods service Build your alternate indexes in advance, using IDCAMS. Rationale and comments

Chapter 10. Processing VSAM files

203

Table 33. Methods for improving VSAM performance (continued) Aspect of VSAM What you can do Buffering For sequential access, request more data buffers; for random access, request more index buffers. Specify both BUFND and BUFNI when ACCESS IS DYNAMIC. Avoid coding additional buffers unless your application will run interactively; then code buffers only when response-time problems arise that might be caused by delays in input and output. Loading records, using access methods services Use the access methods service The REPRO command can update an indexed data set as fast or faster than REPRO command when: v The target indexed data set any COBOL program under these conditions. already contains records. v The input sequential data set contains records to be updated or inserted into the indexed data set. If you use a COBOL program to load the file, use OPEN OUTPUT and ACCESS SEQUENTIAL. File access modes For best performance, access records sequentially. Dynamic access is less efficient than sequential access, but more efficient than random access. Random access results in increased EXCPs because VSAM must access the index for each request. This method compresses the key best. Rationale and comments The default is one index (BUFNI) and two data buffers (BUFND).

Key design

Design the key in the records so that the high-order portion is relatively constant and the low-order portion changes often.

Multiple alternate indexes

Avoid using multiple alternate Updates must be applied through the indexes. primary paths and are reflected through multiple alternate paths, perhaps slowing performance. Use VSAM fixed-length relative data sets rather than VSAM variable-length relative data sets. Although not as space efficient, VSAM fixed-length relative data sets are more runtime efficient than VSAM variable-length relative data sets.

Relative file organization

204

Enterprise COBOL for z/OS V4.2 Programming Guide

Table 33. Methods for improving VSAM performance (continued) Aspect of VSAM What you can do Control interval sizes (CISZ) Provide your system programmer with information about the data access and future growth of your VSAM data sets. From this information, your system programmer can determine the best control interval size (CISZ) and FREESPACE size (FSPC). Rationale and comments VSAM calculates CISZ to best fit the direct-access storage device (DASD) usage algorithm, which might not, however, be efficient for your application.

An average CISZ of 4K is suitable for most applications. A smaller CISZ means faster retrieval for random processing at the expense of inserts (that is, more CISZ splits and therefore Choose proper values for CISZ more space in the data set). A larger and FSPC to minimize control CISZ results in the transfer of more data across the channel for each READ. This is area (CA) splits. You can more efficient for sequential processing, diagnose the current number similar to a large OS BLKSIZE. of CA splits by issuing the LISTCAT ALL command on the Many control area (CA) splits are cluster, and then compress unfavorable for VSAM performance. (using EXPORT, IMPORT, or The FREESPACE value can affect CA REPRO) the cluster to omit all splits, depending on how the file is CA splits periodically. used.

RELATED TASKS

Specifying access modes for VSAM files on page 185 z/OS DFSMS: Using Data Sets (Building a resource pool, Selecting the optimal percentage of free space)
RELATED REFERENCES

z/OS DFSMS: Access Method Services for Catalogs

Chapter 10. Processing VSAM files

205

206

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 11. Processing line-sequential files


Line-sequential files reside in the hierarchical file system (HFS) and contain only printable characters and certain control characters as data. Each record ends with an EBCDIC newline character (X15), which is not included in the record length. Because these are sequential files, records are placed one after another according to entry order. Your program can process these files only sequentially, retrieving (with the READ statement) records in the same order as they are in the file. A new record is placed after the preceding record. To process line-sequential files in your program, use COBOL language statements that: v Identify and describe the files in the ENVIRONMENT DIVISION and the DATA DIVISION v Process the records in the files in the PROCEDURE DIVISION After you have created a record, you cannot change its length or its position in the file, and you cannot delete it.
RELATED TASKS

Defining line-sequential files and records in COBOL Describing the structure of a line-sequential file on page 208 Coding input-output statements for line-sequential files on page 209 Handling errors in line-sequential files on page 212 Defining and allocating line-sequential files on page 209 UNIX System Services Users Guide
RELATED REFERENCES

Allowable control characters on page 208

Defining line-sequential files and records in COBOL


Use the FILE-CONTROL paragraph in the ENVIRONMENT DIVISION to define the files in a COBOL program as line-sequential files, and to associate the files with the corresponding external file-names (ddnames or environment variable names). An external file-name is the name by which a file is known to the operating system. In the following example, COMMUTER-FILE is the name that your program uses for the file; COMMUTR is the external name:
FILE-CONTROL. SELECT COMMUTER-FILE ASSIGN TO COMMUTR ORGANIZATION IS LINE SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS ECODE.

The ASSIGN assignment-name clause must not include an organization field (S- or AS-) before the external name. The ACCESS phrase and the FILE STATUS clause are optional.
RELATED TASKS

Describing the structure of a line-sequential file on page 208


Copyright IBM Corp. 1991, 2009

207

Coding input-output statements for line-sequential files on page 209 Defining and allocating line-sequential files on page 209
RELATED REFERENCES

Allowable control characters

Allowable control characters


The control characters shown in the table below are the only characters other than printable characters that line-sequential files can contain. The hexadecimal values are in EBCDIC.
Hexadecimal value X05 X0B X0C X0D X0E X0F X15 X16 X2F Control character Horizontal tab Vertical tab Form feed Carriage return DBCS shift-out DBCS shift-in Newline Backspace Alarm

The newline character is treated as a record delimiter. The other control characters are treated as data and are part of the record.
RELATED TASKS

Defining line-sequential files and records in COBOL on page 207

Describing the structure of a line-sequential file


In the FILE SECTION, code a file description (FD) entry for the file. In the associated record description entry or entries, define the record-name and record length. Code the logical size in bytes of the records by using the RECORD clause. Line-sequential files are stream files. Because of their character-oriented nature, the physical records are of variable length. The following examples show how the FD entry might look for a line-sequential file: With fixed-length records:
FILE SECTION. FD COMMUTER-FILE RECORD CONTAINS 80 CHARACTERS. 01 COMMUTER-RECORD. 05 COMMUTER-NUMBER PIC X(16). 05 COMMUTER-DESCRIPTION PIC X(64).

With variable-length records:

208

Enterprise COBOL for z/OS V4.2 Programming Guide

FILE SECTION. FD COMMUTER-FILE RECORD VARYING FROM 16 TO 80 CHARACTERS. 01 COMMUTER-RECORD. 05 COMMUTER-NUMBER PIC X(16). 05 COMMUTER-DESCRIPTION PIC X(64).

If you code the same fixed size and no OCCURS DEPENDING ON clause for any level-01 record description entries associated with the file, that fixed size is the logical record length. However, because blanks at the end of a record are not written to the file, the physical records might be of varying lengths.
RELATED TASKS

Defining line-sequential files and records in COBOL on page 207 Coding input-output statements for line-sequential files Defining and allocating line-sequential files
RELATED REFERENCES

Data division--file description entries (Enterprise COBOL Language Reference)

Defining and allocating line-sequential files


You can define a line-sequential file in the HFS by using either a DD statement or an environment variable. Allocation of these files follows the general rules for allocating COBOL files. To define a line-sequential file, code a DD allocation or an environment variable with a name that matches the external name in the ASSIGN clause: v A DD allocation: A DD statement that specifies PATH='absolute-path-name' A TSO allocation that specifies PATH('absolute-path-name') You can optionally also specify these options: PATHOPTS PATHMODE PATHDISP v An environment variable with a value of PATH(absolute-path-name). No other values can be specified. For example, to have your program use HFS file /u/myfiles/commuterfile for a COBOL file that has an assignment-name of COMMUTR, you could use the following command:
export COMMUTR="PATH(/u/myfiles/commuterfile)"
RELATED TASKS

Allocating files on page 149 Defining line-sequential files and records in COBOL on page 207
RELATED REFERENCES

MVS Program Management: Users Guide and Reference

Coding input-output statements for line-sequential files


Code the input and output statements shown below to process a line-sequential file.
Chapter 11. Processing line-sequential files

209

OPEN

To initiate the processing of a file. You can open a line-sequential file as INPUT, OUTPUT, or EXTEND. You cannot open a line-sequential file as I-O.

READ

To read a record from a file. With sequential processing, a program reads one record after another in the same order in which the records were entered when the file was created.

WRITE

To create a record in a file. A program writes new records to the end of the file.

CLOSE

To release the connection between a file and the program.

RELATED TASKS

Defining line-sequential files and records in COBOL on page 207 Describing the structure of a line-sequential file on page 208 Opening line-sequential files Reading records from line-sequential files Adding records to line-sequential files on page 211 Closing line-sequential files on page 211 Handling errors in line-sequential files on page 212
RELATED REFERENCES

OPEN statement (Enterprise COBOL Language Reference) READ statement (Enterprise COBOL Language Reference) WRITE statement (Enterprise COBOL Language Reference) CLOSE statement (Enterprise COBOL Language Reference)

Opening line-sequential files


Before your program can use any READ or WRITE statements to process records in a file, it must first open the file with an OPEN statement. An OPEN statement works if the file is available or has been dynamically allocated. Code CLOSE WITH LOCK so that the file cannot be opened again while the program is running.
RELATED TASKS

Reading records from line-sequential files Adding records to line-sequential files on page 211 Closing line-sequential files on page 211 Defining and allocating line-sequential files on page 209
RELATED REFERENCES

OPEN statement (Enterprise COBOL Language Reference) CLOSE statement (Enterprise COBOL Language Reference)

Reading records from line-sequential files


To read from a line-sequential file, open the file and use the READ statement. Your program reads one record after another in the same order in which the records were entered when the file was created.

210

Enterprise COBOL for z/OS V4.2 Programming Guide

Characters in the file record are read one at a time into the record area until one of the following conditions occurs: v The record delimiter (the EBCDIC newline character) is encountered. The delimiter is discarded and the remainder of the record area is filled with spaces. (Record area is longer than the file record.) v The entire record area is filled with characters. If the next unread character is the record delimiter, it is discarded. The next READ reads from the first character of the next record. (Record area is the same length as the file record.) Otherwise the next unread character is the first character to be read by the next READ. (Record area is shorter than the file record.) v End-of-file is encountered. The remainder of the record area is filled with spaces. (Record area is longer than the file record.)
RELATED TASKS

Opening line-sequential files on page 210 Adding records to line-sequential files Closing line-sequential files Defining and allocating line-sequential files on page 209
RELATED REFERENCES

OPEN statement (Enterprise COBOL Language Reference) WRITE statement (Enterprise COBOL Language Reference)

Adding records to line-sequential files


To add to a line-sequential file, open the file as EXTEND and use the WRITE statement to add records immediately after the last record in the file. Blanks at the end of the record area are removed, and the record delimiter is added. The characters in the record area from the first character up to and including the added record delimiter are written to the file as one record. Records written to line-sequential files must contain only USAGE DISPLAY and DISPLAY-1 items. Zoned decimal data items must be unsigned or declared with the SEPARATE phrase of the SIGN clause if signed.
RELATED TASKS

Opening line-sequential files on page 210 Reading records from line-sequential files on page 210 Closing line-sequential files Defining and allocating line-sequential files on page 209
RELATED REFERENCES

OPEN statement (Enterprise COBOL Language Reference) WRITE statement (Enterprise COBOL Language Reference)

Closing line-sequential files


Use the CLOSE statement to disconnect your program from a line-sequential file. If you try to close a file that is already closed, you will get a logic error.

Chapter 11. Processing line-sequential files

211

If you do not close a line-sequential file, the file is automatically closed for you under the following conditions: v When the run unit ends normally. v When the run unit ends abnormally, if the TRAP(ON) runtime option is set. v When Language Environment condition handling is completed and the application resumes in a routine other than where the condition occurred, open files defined in any COBOL programs in the run unit that might be called again and reentered are closed. You can change the location where the program resumes (after a condition is handled) by moving the resume cursor with the Language Environment CEEMRCR callable service or using HLL language constructs such as a C longjmp call. File status codes are set when these implicit CLOSE operations are performed, but EXCEPTION/ERROR declaratives are not invoked.
RELATED TASKS

Opening line-sequential files on page 210 Reading records from line-sequential files on page 210 Adding records to line-sequential files on page 211 Defining and allocating line-sequential files on page 209
RELATED REFERENCES

CLOSE statement (Enterprise COBOL Language Reference)

Handling errors in line-sequential files


When an input or output statement fails, COBOL does not take corrective action for you. You choose whether your program should continue running after an input or output statement fails. COBOL provides these language elements for intercepting and handling certain line-sequential input and output errors: v End-of-file phrase (AT END) v EXCEPTION/ERROR declarative v FILE STATUS clause If you do not use one of these techniques, an error in processing input or output raises a Language Environment condition. If you use the FILE STATUS clause, be sure to check the key and take appropriate action based on its value. If you do not check the key, your program might continue, but the results will probably not be what you expected.
RELATED TASKS

Coding input-output statements for line-sequential files on page 209 Handling errors in input and output operations on page 235

212

Enterprise COBOL for z/OS V4.2 Programming Guide

Chapter 12. Sorting and merging files


You can arrange records in a particular sequence by using a SORT or MERGE statement. You can mix SORT and MERGE statements in the same COBOL program. SORT statement Accepts input (from a file or an internal procedure) that is not in sequence, and produces output (to a file or an internal procedure) in a requested sequence. You can add, delete, or change records before or after they are sorted. MERGE statement Compares records from two or more sequenced files and combines them in order. You can add, delete, or change records after they are merged. A program can contain any number of sort and merge operations. They can be the same operation performed many times or different operations. However, one operation must finish before another begins. With Enterprise COBOL, your IBM licensed program for sorting and merging must be DFSORT or an equivalent. Where DFSORT is mentioned, you can use any equivalent sort or merge product. COBOL programs that contain SORT or MERGE statements can reside above or below the 16-MB line. The steps you take to sort or merge are generally as follows: 1. Describe the sort or merge file to be used for sorting or merging. 2. Describe the input to be sorted or merged. If you want to process the records before you sort them, code an input procedure. 3. Describe the output from sorting or merging. If you want to process the records after you sort or merge them, code an output procedure. 4. Request the sort or merge. 5. Determine whether the sort or merge operation was successful. Restrictions: v You cannot run a COBOL program that contains SORT or MERGE statements under z/OS UNIX. This restriction includes BPXBATCH. v You cannot use SORT or MERGE statements in programs compiled with the THREAD option. This includes programs that use object-oriented syntax and multithreaded applications, both of which require the THREAD option.
RELATED CONCEPTS

Sort and merge process on page 214


RELATED TASKS

Describing the sort or merge file on page 214 Describing the input to sorting or merging on page 215 Describing the output from sorting or merging on page 217 Requesting the sort or merge on page 220 Determining whether the sort or merge was successful on page 224 Stopping a sort or merge operation prematurely on page 225
Copyright IBM Corp. 1991, 2009

213

Improving sort performance with FASTSRT on page 225 Controlling sort behavior on page 228 DFSORT Application Programming Guide
RELATED REFERENCES

CICS SORT application restrictions on page 232 SORT statement (Enterprise COBOL Language Reference) MERGE statement (Enterprise COBOL Language Reference)

Sort and merge process


During the sorting of a file, all of the records in the file are ordered according to the contents of one or more fields (keys) in each record. You can sort the records in either ascending or descending order of each key. If there are multiple keys, the records are first sorted according to the content of the first (or primary) key, then according to the content of the second key, and so on. To sort a file, use the COBOL SORT statement. During the merging of two or more files (which must already be sorted), the records are combined and ordered according to the contents of one or more keys in each record. You can order the records in either ascending or descending order of each key. As with sorting, the records are first ordered according to the content of the primary key, then according to the content of the second key, and so on. Use MERGE . . . USING to name the files that you want to combine into one sequenced file. The merge operation compares keys in the records of the input files, and passes the sequenced records one by one to the RETURN statement of an output procedure or to the file that you name in the GIVING phrase.
RELATED TASKS

Setting sort or merge criteria on page 221


RELATED REFERENCES

SORT statement (Enterprise COBOL Language Reference) MERGE statement (Enterprise COBOL Language Reference)

Describing the sort or merge file


Describe the sort file to be used for sorting or merging. You need SELECT clauses and SD entries even if you are sorting or merging data items only from WORKING-STORAGE or LOCAL-STORAGE. Code as follows: 1. Write one or more SELECT clauses in the FILE-CONTROL paragraph of the ENVIRONMENT DIVISION to name a sort file. For example:
ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT Sort-Work-1 ASSIGN TO SortFile.

Sort-Work-1 is the name of the file in your program. Use this name to refer to the file.

214

Enterprise COBOL for z/OS V4.2 Programming Guide

2. Describe the sort file in an SD entry in the FILE SECTION of the DATA DIVISION. Every SD entry must contain a record description. For example:
DATA DIVISION. FILE SECTION. SD Sort-Work-1 RECORD CONTAINS 100 CHARACTERS. 01 SORT-WORK-1-AREA. 05 SORT-KEY-1 PIC X(10). 05 SORT-KEY-2 PIC X(10). 05 FILLER PIC X(80).

The file described in an SD entry is the working file used for a sort or merge operation. You cannot perform any input or output operations on this file and you do not need to provide a ddname definition for it.
RELATED REFERENCES

FILE SECTION entries on page 14

Describing the input to sorting or merging


Describe the input file or files for sorting or merging by following the procedure below. 1. Write one or more SELECT clauses in the FILE-CONTROL paragraph of the ENVIRONMENT DIVISION to name the input files. For example:
ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT Input-File ASSIGN TO InFile.

Input-File is the name of the file in your program. Use this name to refer to the file. 2. Describe the input file (or files when merging) in an FD entry in the FILE SECTION of the DATA DIVISION. For example:
DATA DIVISION. FILE SECTION. FD Input-File LABEL RECORDS ARE STANDARD BLOCK CONTAINS 0 CHARACTERS RECORDING MODE IS F RECORD CONTAINS 100 CHARACTERS. 01 Input-Record PIC X(100).
RELATED TASKS

Coding the input procedure on page 216 Requesting the sort or merge on page 220
RELATED REFERENCES

FILE SECTION entries on page 14

Example: describing sort and input files for SORT


The following example shows the ENVIRONMENT DIVISION and DATA DIVISION entries needed to describe sort work files and an input file.
ID Division. Program-ID. SmplSort. Environment Division. Input-Output Section. File-Control.
Chapter 12. Sorting and merging files

215

* * Assign name for a working file is treated as documentation. * Select Sort-Work-1 Assign To SortFile. Select Sort-Work-2 Assign To SortFile. Select Input-File Assign To InFile. . . . Data Division. File Section. SD Sort-Work-1 Record Contains 100 Characters. 01 Sort-Work-1-Area. 05 Sort-Key-1 Pic X(10). 05 Sort-Key-2 Pic X(10). 05 Filler Pic X(80). SD Sort-Work-2 Record Contains 30 Characters. 01 Sort-Work-2-Area. 05 Sort-Key Pic X(5). 05 Filler Pic X(25). FD Input-File Label Records Are Standard Block Contains 0 Characters Recording Mode is F Record Contains 100 Characters. 01 Input-Record Pic X(100). . . . Working-Storage Section. 01 EOS-Sw Pic X. 01 Filler. 05 Table-Entry Occurs 100 Times Indexed By X1 Pic X(30). . . .
RELATED TASKS

Requesting the sort or merge on page 220

Coding the input procedure


To process the records in an input file before they are released to the sort program, use the INPUT PROCEDURE phrase of the SORT statement. You can use an input procedure to: v Release data items to the sort file from WORKING-STORAGE or LOCAL-STORAGE. v Release records that have already been read elsewhere in the program. v Read records from an input file, select or process them, and release them to the sort file. Each input procedure must be contained in either paragraphs or sections. For example, to release records from a table in WORKING-STORAGE or LOCAL-STORAGE to the sort file SORT-WORK-2, you could code as follows:
SORT SORT-WORK-2 ON ASCENDING KEY SORT-KEY INPUT PROCEDURE 600-SORT3-INPUT-PROC . . . 600-SORT3-INPUT-PROC SECTION. PERFORM WITH TEST AFTER VARYING X1 FROM 1 BY 1 UNTIL X1 = 100 RELEASE SORT-WORK-2-AREA FROM TABLE-ENTRY (X1) END-PERFORM.

216

Enterprise COBOL for z/OS V4.2 Programming Guide

To transfer records to the sort program, all input procedures must contain at least one RELEASE or RELEASE FROM statement. To release A from X, for example, you can code:
MOVE X TO A. RELEASE A.

Alternatively, you can code:


RELEASE A FROM X.

The following table compares the RELEASE and RELEASE FROM statements.
RELEASE MOVE EXT-RECORD TO SORT-EXT-RECORD PERFORM RELEASE-SORT-RECORD . . . RELEASE-SORT-RECORD. RELEASE SORT-RECORD RELEASE FROM PERFORM RELEASE-SORT-RECORD . . . RELEASE-SORT-RECORD. RELEASE SORT-RECORD FROM SORT-EXT-RECORD

RELATED REFERENCES

Restrictions on input and output procedures on page 219 RELEASE statement (Enterprise COBOL Language Reference)

Describing the output from sorting or merging


If the output from sorting or merging is a file, describe the file by following the procedure below. 1. Write a SELECT clause in the FILE-CONTROL paragraph of the ENVIRONMENT DIVISION to name the output file. For example:
ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT Output-File ASSIGN TO OutFile.

Output-File is the name of the file in your program. Use this name to refer to the file. 2. Describe the output file (or files when merging) in an FD entry in the FILE SECTION of the DATA DIVISION. For example:
DATA DIVISION. FILE SECTION. FD Output-File LABEL RECORDS ARE STANDARD BLOCK CONTAINS 0 CHARACTERS RECORDING MODE IS F RECORD CONTAINS 100 CHARACTERS. 01 Output-Record PIC X(100).
RELATED TASKS

Coding the output procedure on page 218 Requesting the sort or merge on page 220
RELATED REFERENCES

FILE SECTION entries on page 14

Chapter 12. Sorting and merging files

217

Coding the output procedure


To select, edit, or otherwise change sorted records before writing them from the sort work file into another file, use the OUTPUT PROCEDURE phrase of the SORT statement. Each output procedure must be contained in either a section or a paragraph. An output procedure must include both of the following elements: v At least one RETURN statement or one RETURN statement with the INTO phrase v Any statements necessary to process the records that are made available, one at a time, by the RETURN statement The RETURN statement makes each sorted record available to the output procedure. (The RETURN statement for a sort file is similar to a READ statement for an input file.) You can use the AT END and END-RETURN phrases with the RETURN statement. The imperative statements in the AT END phrase are performed after all the records have been returned from the sort file. The END-RETURN explicit scope terminator delimits the scope of the RETURN statement. If you use RETURN INTO instead of RETURN, the records will be returned to WORKING-STORAGE, LOCAL-STORAGE, or to an output area. DFSORT coding: When you use DFSORT and a RETURN statement does not encounter an AT END condition before a COBOL program finishes running, the SORT statement could end abnormally with DFSORT message IEC025A. To avoid this situation, be sure to code the RETURN statement with the AT END phrase. In addition, ensure that the RETURN statement is executed until the AT END condition is encountered. The AT END condition occurs after the last record is returned to the program from the sort work file and a subsequent RETURN statement is executed. Example: coding the output procedure when using DFSORT
RELATED REFERENCES

Restrictions on input and output procedures on page 219 RETURN statement (Enterprise COBOL Language Reference)

Example: coding the output procedure when using DFSORT


The following example shows a coding technique that ensures that the RETURN statement encounters the AT END condition before the program finishes running. The RETURN statement, coded with the AT END phrase, is executed until the AT END condition occurs.
IDENTIFICATION DIVISION. DATA DIVISION. FILE SECTION. SD OUR-FILE. 01 OUR-SORT-REC. 03 SORT-KEY PIC X(10). 03 FILLER PIC X(70). . . . WORKING-STORAGE SECTION. 01 WS-SORT-REC PIC X(80). 01 END-OF-SORT-FILE-INDICATOR PIC X VALUE 'N'. 88 NO-MORE-SORT-RECORDS VALUE 'Y'. . . .

218

Enterprise COBOL for z/OS V4.2 Programming Guide

PROCEDURE DIVISION. A-CONTROL SECTION. SORT OUR-FILE ON ASCENDING KEY SORT-KEY INPUT PROCEDURE IS B-INPUT OUTPUT PROCEDURE IS C-OUTPUT. . . . B-INPUT SECTION. MOVE . . .. . .. TO WS-SORT-REC. RELEASE OUR-SORT-REC FROM WS-SORT-REC. . . . C-OUTPUT SECTION. DISPLAY 'STARTING READS OF SORTED RECORDS: '. RETURN OUR-FILE AT END SET NO-MORE-SORT-RECORDS TO TRUE. PERFORM WITH TEST BEFORE UNTIL NO-MORE-SORT-RECORDS IF SORT-RETURN = 0 THEN DISPLAY 'OUR-SORT-REC = ' OUR-SORT-REC RETURN OUR-FILE AT END SET NO-MORE-SORT-RECORDS TO TRUE END-IF END-PERFORM.

Restrictions on input and output procedures


Several restrictions apply to each input or output procedure called by SORT and to each output procedure called by MERGE. Observe these restrictions: v The procedure must not contain any SORT or MERGE statements. v You can use ALTER, GO TO, and PERFORM statements in the procedure to refer to procedure-names outside the input or output procedure. However, control must return to the input or output procedure after a GO TO or PERFORM statement. v The remainder of the PROCEDURE DIVISION must not contain any transfers of control to points inside the input or output procedure (with the exception of the return of control from a declarative section). v In an input or output procedure, you can call a program that follows standard linkage conventions. However, the called program cannot issue a SORT or MERGE statement. v During a SORT or MERGE operation, the SD data item is used. You must not use it in the output procedure before the first RETURN executes. If you move data into this record area before the first RETURN statement, the first record to be returned will be overwritten. v Language Environment condition handling does not let user-written condition handlers be established in an input or output procedure.
RELATED TASKS

Coding the input procedure on page 216 Coding the output procedure on page 218 Language Environment Programming Guide (Preparing to link-edit and run)

Defining sort and merge data sets


To use DFSORT under z/OS, code DD statements in the runtime JCL to describe the necessary data sets that are listed below.

Chapter 12. Sorting and merging files

219

Sort or merge work Define a minimum of three data sets: SORTWK01, SORTWK02, SORTWK03, . . ., SORTWKnn (where nn is 99 or less). These data sets cannot be in the HFS. SYSOUT Define for sort diagnostic messages, unless you change the data-set name. (Change the name using either the MSGDDN keyword of the OPTION control statement in the SORT-CONTROL data set, or using the SORT-MESSAGE special register.) SORTCKPT Define if the sort or merge is to take checkpoints. Input and output Define input and output data sets, if any. SORTLIB (DFSORT library) Define the library that contains the sort modules, for example, SYS1.SORTLIB.
RELATED TASKS

Controlling sort behavior on page 228 Using checkpoint/restart with DFSORT on page 231

Sorting variable-length records


Your sort work file will be variable length only if you define it to be variable length, even if the input file to the sort contains variable-length records. The compiler determines that the sort work file is variable length if you code one of the following elements in the SD entry: v A RECORD IS VARYING clause v Two or more record descriptions that define records that have different sizes, or records that contain an OCCURS DEPENDING ON clause You cannot use RECORDING MODE V for the sort work file because the SD entry does not allow the RECORDING MODE clause. Performance consideration: To improve sort performance of variable-length files, specify the most frequently occurring record length of the input file (the modal length) on the SMS= control card or in the SORT-MODE-SIZE special register.
RELATED TASKS

Changing DFSORT defaults with control statements on page 229 Controlling sort behavior on page 228

Requesting the sort or merge


To read records from an input file (files for MERGE) without preliminary processing, use SORT . . . USING or MERGE . . . USING and the name of the input file (files) that you declared in a SELECT clause. To transfer sorted or merged records from the sort or merge program to another file without any further processing, use SORT . . . GIVING or MERGE . . . GIVING and the name of the output file that you declared in a SELECT clause. For example:

220

Enterprise COBOL for z/OS V4.2 Programming Guide

SORT Sort-Work-1 ON ASCENDING KEY Sort-Key-1 USING Input-File GIVING Output-File.

For SORT . . . USING or MERGE . . . USING, the compiler generates an input procedure to open the file (files), read the records, release the records to the sort or merge program, and close the file (files). The file (files) must not be open when the SORT or MERGE statement begins execution. For SORT . . . GIVING or MERGE . . . GIVING, the compiler generates an output procedure to open the file, return the records, write the records, and close the file. The file must not be open when the SORT or MERGE statement begins execution. The USING or GIVING files in a SORT or MERGE statement can be sequential files residing in the HFS. Example: describing sort and input files for SORT on page 215 If you want an input procedure to be performed on the sort records before they are sorted, use SORT . . . INPUT PROCEDURE. If you want an output procedure to be performed on the sorted records, use SORT . . . OUTPUT PROCEDURE. For example:
SORT Sort-Work-1 ON ASCENDING KEY Sort-Key-1 INPUT PROCEDURE EditInputRecords OUTPUT PROCEDURE FormatData.

Example: sorting with input and output procedures on page 222 Restriction: You cannot use an input procedure with the MERGE statement. The source of input to the merge operation must be a collection of already sorted files. However, if you want an output procedure to be performed on the merged records, use MERGE . . . OUTPUT PROCEDURE. For example:
MERGE Merge-Work ON ASCENDING KEY Merge-Key USING Input-File-1 Input-File-2 Input-File-3 OUTPUT PROCEDURE ProcessOutput.

In the FILE SECTION, you must define Merge-Work in an SD entry, and the input files in FD entries.
RELATED TASKS

Defining sort and merge data sets on page 219


RELATED REFERENCES

SORT statement (Enterprise COBOL Language Reference) MERGE statement (Enterprise COBOL Language Reference)

Setting sort or merge criteria


To set sort or merge criteria, define the keys on which the operation is to be performed. Do these steps: 1. In the record description of the files to be sorted or merged, define the key or keys.

Chapter 12. Sorting and merging files

221

There is no maximum number of keys, but the keys must be located in the first 4092 bytes of the record description. The total length of the keys cannot exceed 4092 bytes unless the EQUALS keyword is coded in the DFSORT OPTION control statement, in which case the total length of the keys must not exceed 4088 bytes. Restriction: A key cannot be variably located. 2. In the SORT or MERGE statement, specify the key fields to be used for sequencing by coding the ASCENDING or DESCENDING KEY phrase, or both. When you code more than one key, some can be ascending, and some descending. Specify the names of the keys in decreasing order of significance. The leftmost key is the primary key. The next key is the secondary key, and so on. SORT and MERGE keys can be of class alphabetic, alphanumeric, national, or numeric (but not numeric of USAGE NATIONAL). If it has USAGE NATIONAL, a key can be of category national or can be a national-edited or numeric-edited data item. A key cannot be a national decimal data item or a national floating-point data item. The collation order for national keys is determined by the binary order of the keys. If you specify a national data item as a key, any COLLATING SEQUENCE phrase in the SORT or MERGE statement does not apply to that key. You can mix SORT and MERGE statements in the same COBOL program. A program can perform any number of sort or merge operations. However, one operation must end before another can begin.
RELATED REFERENCES

DFSORT Application Programming Guide (SORT control statement) SORT statement (Enterprise COBOL Language Reference) MERGE statement (Enterprise COBOL Language Reference)

Example: sorting with input and output procedures


The following example shows the use of an input and an output procedure in a SORT statement. The example also shows how you can define a primary key (SORT-GRID-LOCATION) and a secondary key (SORT-SHIFT) before using them in the SORT statement.
DATA DIVISION. . . . SD SORT-FILE RECORD CONTAINS 115 CHARACTERS DATA RECORD SORT-RECORD. 01 SORT-RECORD. 05 SORT-KEY. 10 SORT-SHIFT PIC X(1). 10 SORT-GRID-LOCATION PIC X(2). 10 SORT-REPORT PIC X(3). 05 SORT-EXT-RECORD. 10 SORT-EXT-EMPLOYEE-NUM PIC X(6). 10 SORT-EXT-NAME PIC X(30). 10 FILLER PIC X(73). . . . WORKING-STORAGE SECTION. 01 TAB1. 05 TAB-ENTRY OCCURS 10 TIMES INDEXED BY TAB-INDX. 10 WS-SHIFT PIC X(1). 10 WS-GRID-LOCATION PIC X(2). 10 WS-REPORT PIC X(3).

222

Enterprise COBOL for z/OS V4.2 Programming Guide

10 10 10

WS-EXT-EMPLOYEE-NUM WS-EXT-NAME FILLER

PIC X(6). PIC X(30). PIC X(73).

. . . PROCEDURE DIVISION. . . . SORT SORT-FILE ON ASCENDING KEY SORT-GRID-LOCATION SORT-SHIFT INPUT PROCEDURE 600-SORT3-INPUT OUTPUT PROCEDURE 700-SORT3-OUTPUT. . . . 600-SORT3-INPUT. PERFORM VARYING TAB-INDX FROM 1 BY 1 UNTIL TAB-INDX > 10 RELEASE SORT-RECORD FROM TAB-ENTRY(TAB-INDX) END-PERFORM. . . . 700-SORT3-OUTPUT. PERFORM VARYING TAB-INDX FROM 1 BY 1 UNTIL TAB-INDX > 10 RETURN SORT-FILE INTO TAB-ENTRY(TAB-INDX) AT END DISPLAY 'Out Of Records In SORT File' END-RETURN END-PERFORM.
RELATED TASKS

Requesting the sort or merge on page 220

Choosing alternate collating sequences


You can sort or merge records on the EBCDIC or ASCII collating sequence, or on another collating sequence. The default collating sequence is EBCDIC unless you code the PROGRAM COLLATING SEQUENCE clause in the OBJECT-COMPUTER paragraph. To override the default sequence, use the COLLATING SEQUENCE phrase of the SORT or MERGE statement. You can use different collating sequences for each SORT or MERGE statement in your program. The PROGRAM COLLATING SEQUENCE clause and the COLLATING SEQUENCE phrase apply only to keys of class alphabetic or alphanumeric. When you sort or merge an ASCII file, you have to request the ASCII collating sequence. To do so, code the COLLATING SEQUENCE phrase of the SORT or MERGE statement, and define the alphabet-name as STANDARD-1 in the SPECIAL-NAMES paragraph.
RELATED TASKS

Specifying the collating sequence on page 9 Setting sort or merge criteria on page 221
RELATED REFERENCES

OBJECT-COMPUTER paragraph (Enterprise COBOL Language Reference) SORT statement (Enterprise COBOL Language Reference) Classes and categories of data (Enterprise COBOL Language Reference)

Sorting on windowed date fields


You can specify windowed date fields as sort keys if your version of DFSORT supports the Y2PAST option. If so, DFSORT can sort or merge on the windowed date sequence.

Chapter 12. Sorting and merging files

223

To sort on a windowed date field, use the DATE FORMAT clause to define a windowed date field; then use the field as the sort key. DFSORT will use the same century window as that used by the compilation unit. Specify the century window with the YEARWINDOW compiler option. DFSORT supports year-last windowed date fields, although the compiler itself does not provide automatic windowing for year-last windowed date fields in statements other than MERGE or SORT.
RELATED CONCEPTS

Millennium language extensions (MLE) on page 636


RELATED TASKS

Sorting and merging by date on page 650


RELATED REFERENCES

YEARWINDOW on page 360 DATE FORMAT clause (Enterprise COBOL Language Reference) DFSORT Application Programming Guide (OPTION control statement: Y2PAST)

Preserving the original sequence of records with equal keys


You can preserve the order of identical collating records from input to output. Use one of these techniques: v Install DFSORT with the EQUALS option as the default. v Provide, at run time, an OPTION card that has the EQUALS keyword in the IGZSRTCD data set. v Use the WITH DUPLICATES IN ORDER phrase in the SORT statement. Doing so adds the EQUALS keyword to the OPTION card in the IGZSRTCD data set. Do not use both the NOEQUALS keyword on the OPTION card and the DUPLICATES phrase, or the run unit will end.
RELATED REFERENCES

DFSORT Application Programming Guide (OPTION control statement)

Determining whether the sort or merge was successful


The DFSORT program returns a completion code of either 0 (successful completion) or 16 (unsuccessful completion) after each sort or merge has finished. The completion code is stored in the SORT-RETURN special register. You should test for successful completion after each SORT or MERGE statement. For example:
SORT SORT-WORK-2 ON ASCENDING KEY SORT-KEY INPUT PROCEDURE IS 600-SORT3-INPUT-PROC OUTPUT PROCEDURE IS 700-SORT3-OUTPUT-PROC. IF SORT-RETURN NOT=0 DISPLAY "SORT ENDED ABNORMALLY. SORT-RETURN = " SORT-RETURN. . . . 600-SORT3-INPUT-PROC SECTION. . . . 700-SORT3-OUTPUT-PROC SECTION. . . .

224

Enterprise COBOL for z/OS V4.2 Programming Guide

If you do not reference SORT-RETURN anywhere in your program, the COBOL run time tests the completion code. If it is 16, COBOL issues a runtime diagnostic message. By default, DFSORT diagnostic messages are sent to the SYSOUT data set. If you want to change this default, use the MSGDDN parameter of the DFSORT OPTION control card or use the SORT-MESSAGE special register. If you test SORT-RETURN for one or more (but not necessarily all) SORT or MERGE statements, the COBOL run time does not check the completion code.
RELATED TASKS

Checking for sort errors with NOFASTSRT on page 227 Controlling sort behavior on page 228
RELATED REFERENCES

DFSORT Application Programming Guide (DFSORT messages and return codes)

Stopping a sort or merge operation prematurely


To stop a sort or merge operation, move the integer 16 into the SORT-RETURN special register. Move 16 into the register in either of the following ways: v Use MOVE in an input or output procedure. Sort or merge processing will be stopped immediately after the next RELEASE or RETURN statement is performed. v Reset the register in a declarative section entered during processing of a USING or GIVING file. Sort or merge processing will be stopped immediately after the next implicit RELEASE or RETURN is performed, which will occur after a record has been read from or written to the USING or GIVING file. Control then returns to the statement following the SORT or MERGE statement.

Improving sort performance with FASTSRT


Using the FASTSRT compiler option improves the performance of most sort operations. With FASTSRT, the DFSORT product (instead of Enterprise COBOL) performs the I/O on the input and output files you name in the SORT . . . USING and SORT . . . GIVING statements. The compiler issues informational messages to point out statements in which FASTSRT can improve performance. Usage notes v You cannot use the DFSORT options SORTIN or SORTOUT if you use FASTSRT. The FASTSRT compiler option does not apply to line-sequential files you use as USING or GIVING files. v If you specify file status and use FASTSRT, file status is ignored during the sort.
RELATED REFERENCES

FASTSRT on page 322


Chapter 12. Sorting and merging files

225

FASTSRT requirements for JCL FASTSRT requirements for sort input and output files

FASTSRT requirements for JCL


In the runtime JCL, you must assign the sort work files (SORTWKnn) to a direct-access device, not to tape data sets. For the input and output files, the DCB parameter of the DD statement must match the FD description.

FASTSRT requirements for sort input and output files


If you specify FASTSRT but your code does not meet FASTSRT requirements, the compiler issues a message and the COBOL run time performs the I/O instead. Your program will not experience the performance improvements that are otherwise possible. To use FASTSRT, you must describe and process the input files to the sort and the output files from the sort in these ways: v You can name only one input file in the USING phrase. You can name only one output file in the GIVING phrase. v You cannot use an input procedure on an input file nor an output procedure on an output file. Instead of using input or output procedures, you might be able to use these DFSORT control statements: INREC OUTFILE OUTREC INCLUDE OMIT STOPAFT

SKIPREC SUM Many DFSORT functions perform the same operations that are common in input or output procedures. Code the appropriate DFSORT control statements instead, and place them either in the IGZSRTCD or SORTCNTL data set. v Do not code the LINAGE clause for the output FD entry. v Do not code any INPUT declarative (for input files), OUTPUT declarative (for output files), or file-specific declaratives (for either input or output files) to apply to any FDs used in the sort. v Do not use a variable relative file as the input or output file. v Do not use a line-sequential file as the input or output file. v For either an input or an output file, the record descriptions of the SD and FD entry must define the same format (fixed or variable), and the largest records of the SD and FD entry must define the same record length. If you code a RELATIVE KEY clause for an output file, it will not be set by the sort. Performance tip: If you block your input and output records, the sort performance could be significantly improved.

226

Enterprise COBOL for z/OS V4.2 Programming Guide

QSAM requirements
v QSAM files must have a record format of fixed, variable, or spanned. v A QSAM input file can be empty. v To use the same QSAM file for both input and output, you must describe the file using two different DD statements. For example, in the FILE-CONTROL SECTION you might code this:
SELECT FILE-IN ASSIGN INPUTF. SELECT FILE-OUT ASSIGN OUTPUTF.

In the DATA DIVISION, you would have an FD entry for both FILE-IN and FILE-OUT, where FILE-IN and FILE-OUT are identical except for their names. In the PROCEDURE DIVISION, your SORT statement could look like this:
SORT file-name ASCENDING KEY data-name-1 USING FILE-IN GIVING FILE-OUT

Then in your JCL, assuming that data set INOUT has been cataloged, you would code:
//INPUTF DD DSN=INOUT,DISP=SHR //OUTPUTF DD DSN=INOUT,DISP=SHR

On the other hand, if you code the same file-name in the USING and GIVING phrases, or assign the input and output files the same ddname, then the file can be accepted for FASTSRT either for input or output, but not both. If no other conditions disqualify the file from being eligible for FASTSRT on input, then the file will be accepted for FASTSRT on input, but not on output. If the file was found to be ineligible for FASTSRT on input, it might be eligible for FASTSRT on output. A QSAM file that qualifies for FASTSRT can be accessed by the COBOL program while the SORT statement is being performed. For example, if the file is used for FASTSRT on input, you can access it in an output procedure; if it is used for FASTSRT on output, you can access it in an input procedure.

VSAM requirements
v A VSAM input file must not be empty. v VSAM files cannot be password-protected. v You cannot name the same VSAM file in both the USING and GIVING phrases. v A VSAM file that qualifies for FASTSRT cannot be accessed by the COBOL program until the SORT statement processing is completed. For example, if the file qualifies for FASTSRT on input, you cannot access it in an output procedure and vice versa. (If you do so, OPEN fails.)
RELATED TASKS

DFSORT Application Programming Guide

Checking for sort errors with NOFASTSRT


When you compile with the NOFASTSRT option, the sort process does not check for errors in open, close, or input or output operations for files that you reference in the USING or GIVING phrase of the SORT statement. Therefore, you might need to check whether SORT completed successfully. The code required depends on whether you code a FILE STATUS clause or an ERROR declarative for the files referenced in the USING and GIVING phrases, as shown in the table below.
Chapter 12. Sorting and merging files

227

Table 34. Methods for checking for sort errors with NOFASTSRT FILE STATUS clause? No Yes ERROR declarative? No No Then do: No special coding. Any failure during the sort process causes the program to end abnormally. Test the SORT-RETURN special register after the SORT statement, and test the file status key. (Not recommended if you want complete file-status checking, because the file status code is set but COBOL cannot check it.) In the ERROR declarative, set the SORT-RETURN special register to 16 to stop the sort process and indicate that it was not successful. Test the SORT-RETURN special register after the SORT statement.

Maybe

Yes

RELATED TASKS

Determining whether the sort or merge was successful on page 224 Using file status keys on page 239 Coding ERROR declaratives on page 238 Stopping a sort or merge operation prematurely on page 225

Controlling sort behavior


You can control several aspects of sort behavior by inserting values in special registers before the sort or by using compiler options. You might also have a choice of control statements and keywords. You can verify sort behavior by examining the contents of special registers after the sort. The table below lists those aspects of sort behavior that you can affect by using special registers or compiler options, and the equivalent sort control statement keywords if any are available.
Table 35. Methods for controlling sort behavior Use this special register or compiler option Or this control statement (and keyword if applicable)

To set or test Amount of main storage to be reserved Amount of main storage to be used Modal length of records in a file with variable-length records

SORT-CORE-SIZE special register OPTION (keyword RESINV) SORT-CORE-SIZE special register OPTION (keywords MAINSIZE or MAINSIZE=MAX) SORT-MODE-SIZE special register SMS=nnnnn

Name of sort control statement SORT-CONTROL special register data set (default IGZSRTCD) Name of sort message file (default SYSOUT) Number of sort records Sort completion code SORT-MESSAGE special register

None OPTION (keyword MSGDDN)

SORT-FILE-SIZE special register OPTION (keyword FILSZ) SORT-RETURN special register None

228

Enterprise COBOL for z/OS V4.2 Programming Guide

Table 35. Methods for controlling sort behavior (continued) Use this special register or compiler option Or this control statement (and keyword if applicable) OPTION (keyword Y2PAST) SORT (keyword FORMAT=Y2x)

To set or test

Century window for sorting or YEARWINDOW c