COBOL Programming Guide
COBOL Programming Guide
Programming Guide
Version 3 Release 2
SC27-1412-01
Enterprise COBOL for z/OS and OS/390
Programming Guide
Version 3 Release 2
SC27-1412-01
Note!
Before using this information and the product it supports, be sure to read the general information under “Notices” on
page 699.
iv Programming Guide
Chapter 10. Processing VSAM files 147 Sorting variable-length records . . . . . . . 186
VSAM files . . . . . . . . . . . . . . 148 Requesting the sort or merge . . . . . . . . 186
Defining VSAM file organization and records . . 149 Setting sort or merge criteria . . . . . . . 187
Specifying sequential organization for VSAM Example: sorting with input and output
files . . . . . . . . . . . . . . . 150 procedures . . . . . . . . . . . . . 188
Specifying indexed organization for VSAM files 150 Choosing alternate collating sequences . . . . 188
Specifying relative organization for VSAM files 151 Sorting on windowed date fields . . . . . . 189
Specifying access modes for VSAM files . . . 153 Preserving the original sequence of records with
Defining record lengths for VSAM files. . . . 154 equal keys . . . . . . . . . . . . . 189
Coding input and output statements for VSAM Determining whether the sort or merge was
files . . . . . . . . . . . . . . . . 155 successful . . . . . . . . . . . . . . 190
File position indicator . . . . . . . . . 157 Stopping a sort or merge operation prematurely 190
Opening a file (ESDS, KSDS, or RRDS) . . . . 157 Improving sort performance with FASTSRT . . . 191
Reading records from a VSAM file . . . . . 159 FASTSRT requirements for JCL . . . . . . 191
Updating records in a VSAM file . . . . . . 160 FASTSRT requirements for sort input and
Adding records to a VSAM file . . . . . . 161 output files . . . . . . . . . . . . . 191
Replacing records in a VSAM file. . . . . . 162 Checking for sort errors with NOFASTSRT . . . 193
Deleting records from a VSAM file . . . . . 162 Controlling sort behavior . . . . . . . . . 193
Closing VSAM files . . . . . . . . . . 162 Sort special registers . . . . . . . . . . 194
Handling errors in VSAM files . . . . . . . 163 Changing DFSORT defaults with control
Protecting VSAM files with a password . . . . 164 statements . . . . . . . . . . . . . 195
Example: password protection for a VSAM Allocating storage for sort or merge operations 195
indexed file . . . . . . . . . . . . . 164 Allocating space for sort files . . . . . . . 196
Working with VSAM data sets under z/OS and Using checkpoint/restart with DFSORT . . . . 196
UNIX . . . . . . . . . . . . . . . . 165 Sorting under CICS . . . . . . . . . . . 197
Defining VSAM files . . . . . . . . . . 165 CICS SORT application restrictions . . . . . 197
Creating alternate indexes . . . . . . . . 166
Allocating VSAM files . . . . . . . . . 168 Chapter 13. Processing XML
Sharing VSAM files through RLS . . . . . . 170 documents . . . . . . . . . . . . 199
Improving VSAM performance . . . . . . . 171 XML parser in COBOL . . . . . . . . . . 199
Accessing XML documents . . . . . . . . . 201
Chapter 11. Processing line-sequential Parsing XML documents . . . . . . . . . 201
files . . . . . . . . . . . . . . . 173 Processing XML events . . . . . . . . . 202
Defining line-sequential files and records in Writing procedures to process XML . . . . . 208
COBOL . . . . . . . . . . . . . . . 173 Understanding XML document encoding . . . . 213
Allowable control characters . . . . . . . 174 Specifying the code page . . . . . . . . 214
Describing the structure of a line-sequential file 174 Parsing documents in other code pages. . . . 214
Defining and allocating line-sequential files . . . 175 Handling errors in XML documents . . . . . . 215
Coding input-output statements for line-sequential Unhandled exceptions . . . . . . . . . 216
files . . . . . . . . . . . . . . . . 175 Handling exceptions . . . . . . . . . . 216
Opening line-sequential files . . . . . . . 176 Terminating the parse . . . . . . . . . 217
Reading records from line-sequential files . . . 176 CCSID conflict exception . . . . . . . . 217
Adding records to line-sequential files . . . . 177
Closing line-sequential files. . . . . . . . 177 Chapter 14. Handling errors . . . . . 221
Handling errors in line-sequential files . . . . . 178 Requesting dumps . . . . . . . . . . . 221
Creating a formatted dump. . . . . . . . 221
Chapter 12. Sorting and merging files 179 Creating a system dump . . . . . . . . 222
Sort and merge process . . . . . . . . . . 180 Handling errors in joining and splitting strings . . 222
Describing the sort or merge file . . . . . . . 180 Handling errors in arithmetic operations . . . . 223
Describing the input to sorting or merging . . . 181 Example: checking for division by zero . . . . 223
Example: describing sort and input files for Handling errors in input and output operations 223
SORT . . . . . . . . . . . . . . . 181 Using the end-of-file condition (AT END) . . . 226
Coding the input procedure . . . . . . . . 182 Coding ERROR declaratives . . . . . . . 227
Describing the output from sorting or merging . . 183 Using file status keys . . . . . . . . . . 228
Coding the output procedure . . . . . . . . 183 Example: file status key . . . . . . . . . 229
Coding considerations when using DFSORT . . 184 Using VSAM return codes (VSAM files only) 229
Example: coding the output procedure when Example: checking VSAM status codes . . . . 230
using DFSORT . . . . . . . . . . . . 184 Coding INVALID KEY phrases . . . . . . 231
Restrictions on input and output procedures . . . 185 Example: FILE STATUS and INVALID KEY . . 232
Defining sort and merge data sets . . . . . . 185 Handling errors when calling programs . . . . 233
Contents v
Writing routines for handling errors . . . . . . 233 Chapter 17. Compiling, linking, and
running OO applications . . . . . . 277
Part 2. Compiling and debugging Compiling, linking, and running OO applications
your program . . . . . . . . . . 235 under UNIX . . . . . . . . . . . . . . 277
Compiling OO applications under UNIX . . . 277
Preparing OO applications under UNIX . . . 278
Chapter 15. Compiling under z/OS 237 Example: compiling and linking a COBOL class
Compiling with JCL . . . . . . . . . . . 237 definition under UNIX . . . . . . . . . 279
Using a cataloged procedure . . . . . . . 238 Running OO applications under UNIX . . . . 279
Writing JCL to compile programs. . . . . . 248 Compiling, linking, and running OO applications
Compiling under TSO . . . . . . . . . . 249 using JCL or TSO/E . . . . . . . . . . . 281
Example: ALLOCATE and CALL for compiling Compiling OO applications using JCL or TSO/E 281
under TSO . . . . . . . . . . . . . 250 Preparing and running OO applications using
Example: CLIST for compiling under TSO . . . 250 JCL or TSO/E . . . . . . . . . . . . 282
Starting the compiler from an assembler program 251 Example: compiling, linking, and running an
Defining compiler input and output . . . . . . 252 OO application using JCL . . . . . . . . 283
Data sets used by the compiler under z/OS . . 253
Defining the source code data set (SYSIN) . . . 255
Chapter 18. Compiler options . . . . 287
Specifying source libraries (SYSLIB) . . . . . 255
Option settings for COBOL 85 Standard
Defining the output data set (SYSPRINT) . . . 256
conformance. . . . . . . . . . . . . . 289
Directing compiler messages to your terminal
Conflicting compiler options . . . . . . . . 289
(SYSTERM) . . . . . . . . . . . . . 256
ADATA . . . . . . . . . . . . . . . 290
Creating object code (SYSLIN or SYSPUNCH) 256
ADV . . . . . . . . . . . . . . . . 291
Creating an associated data file (SYSADATA) 257
ARITH . . . . . . . . . . . . . . . 291
Defining the output Java data set (SYSJAVA) 257
AWO . . . . . . . . . . . . . . . . 292
Defining the debug data set (SYSDEBUG) . . . 257
BUFSIZE . . . . . . . . . . . . . . . 292
Specifying compiler options under z/OS . . . . 258
CICS . . . . . . . . . . . . . . . . 293
Specifying compiler options with the PROCESS
CODEPAGE . . . . . . . . . . . . . . 294
(CBL) statement . . . . . . . . . . . 258
COMPILE . . . . . . . . . . . . . . 294
Example: specifying compiler options using JCL 259
CURRENCY . . . . . . . . . . . . . . 295
Example: specifying compiler options under
DATA . . . . . . . . . . . . . . . . 296
TSO . . . . . . . . . . . . . . . 259
DATEPROC . . . . . . . . . . . . . . 297
Compiler options and compiler output under
DBCS . . . . . . . . . . . . . . . . 298
z/OS . . . . . . . . . . . . . . . 259
DECK . . . . . . . . . . . . . . . . 298
Compiling multiple programs (batch compilation) 261
DIAGTRUNC . . . . . . . . . . . . . 298
Example: batch compilation . . . . . . . 261
DLL . . . . . . . . . . . . . . . . 299
Specifying compiler options in a batch
DUMP . . . . . . . . . . . . . . . 300
compilation . . . . . . . . . . . . . 262
DYNAM . . . . . . . . . . . . . . . 301
Example: precedence of options in a batch
EXIT . . . . . . . . . . . . . . . . 301
compilation . . . . . . . . . . . . . 263
EXPORTALL . . . . . . . . . . . . . 301
Example: LANGUAGE option in a batch
FASTSRT . . . . . . . . . . . . . . . 302
compilation . . . . . . . . . . . . . 264
FLAG . . . . . . . . . . . . . . . . 302
Correcting errors in your source program . . . . 265
FLAGSTD . . . . . . . . . . . . . . 303
Generating a list of compiler error messages . . 265
INTDATE . . . . . . . . . . . . . . 304
Messages and listings for compiler-detected
LANGUAGE . . . . . . . . . . . . . 305
errors . . . . . . . . . . . . . . . 266
LIB . . . . . . . . . . . . . . . . . 306
Format of compiler error messages . . . . . 266
LINECOUNT . . . . . . . . . . . . . 306
Severity codes for compiler error messages . . 267
LIST . . . . . . . . . . . . . . . . 306
MAP . . . . . . . . . . . . . . . . 307
Chapter 16. Compiling under UNIX 269 NAME . . . . . . . . . . . . . . . 308
Setting environment variables under UNIX . . . 269 NSYMBOL . . . . . . . . . . . . . . 309
Specifying compiler options under UNIX . . . . 270 NUMBER . . . . . . . . . . . . . . 309
Compiling and linking with the cob2 command 271 NUMPROC . . . . . . . . . . . . . . 310
Defining input and output . . . . . . . . 271 OBJECT . . . . . . . . . . . . . . . 311
Creating a DLL . . . . . . . . . . . . 272 OFFSET . . . . . . . . . . . . . . . 312
Example: using cob2 to compile under UNIX 272 OPTIMIZE . . . . . . . . . . . . . . 312
cob2 . . . . . . . . . . . . . . . 273 Unused data items . . . . . . . . . . 312
cob2 input and output files . . . . . . . . 274 OUTDD . . . . . . . . . . . . . . . 313
Compiling using scripts . . . . . . . . . . 275 PGMNAME . . . . . . . . . . . . . . 314
PGMNAME(COMPAT) . . . . . . . . . 314
vi Programming Guide
PGMNAME(LONGUPPER). . . . . . . . 314 Chapter 20. Developing COBOL
PGMNAME(LONGMIXED) . . . . . . . 315 programs for CICS . . . . . . . . . 375
QUOTE/APOST . . . . . . . . . . . . 316 Coding COBOL programs to run under CICS . . 375
RENT . . . . . . . . . . . . . . . . 316 Coding file input and output . . . . . . . 376
RMODE . . . . . . . . . . . . . . . 317 Retrieving the system date and time. . . . . 376
SEQUENCE . . . . . . . . . . . . . . 318 Displaying the contents of data items . . . . 377
SIZE . . . . . . . . . . . . . . . . 318 Calling to or from COBOL programs . . . . 377
SOURCE . . . . . . . . . . . . . . . 319 Coding nested programs . . . . . . . . 377
SPACE . . . . . . . . . . . . . . . 319 Coding a COBOL program to run above the
SQL . . . . . . . . . . . . . . . . 320 16-MB line . . . . . . . . . . . . . 378
SSRANGE . . . . . . . . . . . . . . 321 Determining the success of ECI calls. . . . . 378
TERMINAL . . . . . . . . . . . . . . 321 Compiling with the CICS option . . . . . . . 378
TEST . . . . . . . . . . . . . . . . 322 Compiling a sequence of programs . . . . . 379
THREAD . . . . . . . . . . . . . . . 325 Separating CICS suboptions . . . . . . . 379
TRUNC . . . . . . . . . . . . . . . 326 Integrated CICS translator . . . . . . . . 380
TRUNC example 1 . . . . . . . . . . 327 Using the separate CICS translator . . . . . . 381
TRUNC example 2 . . . . . . . . . . 328 CICS reserved-word table . . . . . . . . . 382
VBREF . . . . . . . . . . . . . . . 329 Handling errors by using CICS HANDLE . . . . 383
WORD . . . . . . . . . . . . . . . 329 Example: handling errors by using CICS
XREF . . . . . . . . . . . . . . . . 330 HANDLE . . . . . . . . . . . . . 383
YEARWINDOW . . . . . . . . . . . . 331
ZWB . . . . . . . . . . . . . . . . 331
Compiler-directing statements . . . . . . . . 332
Chapter 21. Programming for a DB2
environment . . . . . . . . . . . . 385
Chapter 19. Debugging . . . . . . . 337 Coding SQL statements . . . . . . . . . . 385
Using SQL INCLUDE with the DB2 coprocessor 385
Debugging with source language . . . . . . . 338
Using character data . . . . . . . . . . 385
Tracing program logic . . . . . . . . . 338
Using binary items . . . . . . . . . . 386
Finding and handling input-output errors . . . 339
Determining the success of SQL statements . . 387
Validating data . . . . . . . . . . . . 339
Compiling with the SQL option . . . . . . . 387
Finding uninitialized data . . . . . . . . 339
Compiling in batch . . . . . . . . . . 388
Generating information about procedures . . . 340
Separating DB2 suboptions . . . . . . . . 388
Debugging using compiler options . . . . . . 341
DB2 coprocessor . . . . . . . . . . . 388
Finding coding errors . . . . . . . . . 342
Finding line sequence problems . . . . . . 343
Checking for valid ranges . . . . . . . . 343 Chapter 22. Developing COBOL
Selecting the level of error to be diagnosed . . 344 programs for IMS. . . . . . . . . . 391
Finding program entity definitions and Compiling and linking COBOL programs for
references . . . . . . . . . . . . . 345 running under IMS . . . . . . . . . . . 391
Listing data items . . . . . . . . . . . 346 Using object-oriented COBOL and Java under IMS 392
Getting listings . . . . . . . . . . . . . 347 Calling a COBOL method from an IMS Java
Example: short listing . . . . . . . . . 348 application . . . . . . . . . . . . . 392
Example: SOURCE and NUMBER output . . . 351 Building a mixed COBOL and Java application
Example: embedded map summary . . . . . 353 that starts with COBOL . . . . . . . . . 393
Terms used in MAP output. . . . . . . . 354 Writing mixed-language applications . . . . 394
Symbols used in LIST and MAP output . . . 354
Example: nested program map . . . . . . 356 Chapter 23. Running COBOL
Reading LIST output . . . . . . . . . . 356 programs under UNIX . . . . . . . . 397
Example: XREF output - data-name
Running in UNIX environments . . . . . . . 397
cross-references. . . . . . . . . . . . 368
Setting and accessing environment variables . . . 398
Example: XREF output - program-name
Setting environment variables that affect
cross-references. . . . . . . . . . . . 369
execution . . . . . . . . . . . . . . 398
Example: embedded cross-reference . . . . . 369
Resetting environment variables . . . . . . 399
Example: OFFSET compiler output . . . . . 370
Accessing environment variables . . . . . . 399
Example: VBREF compiler output . . . . . 371
Example: accessing environment variables . . . 400
Preparing to use the debugger. . . . . . . . 371
Calling UNIX/POSIX APIs . . . . . . . . . 400
fork(), exec(), and spawn() . . . . . . . . 400
Part 3. Targeting COBOL programs Samples . . . . . . . . . . . . . . 401
for certain environments . . . . . 373 Accessing main program parameters . . . . . 402
Example: accessing main program parameters 402
Contents vii
Part 4. Structuring complex Using DLLs in OO COBOL applications . . . . 446
applications . . . . . . . . . . . 405
Chapter 27. Preparing COBOL
programs for multithreading . . . . . 449
Chapter 24. Using subprograms . . . 407
Multithreading . . . . . . . . . . . . . 449
Main programs, subprograms, and calls . . . . 408
Choosing THREAD to support multithreading . . 451
Ending and reentering main programs or
Transferring control with multithreading . . . . 451
subprograms . . . . . . . . . . . . . 408
Using cancel with threaded programs . . . . 451
Transferring control to another program . . . . 410
Ending a program . . . . . . . . . . . 451
Making static calls. . . . . . . . . . . 410
Preinitializing the COBOL environment . . . 452
Making dynamic calls . . . . . . . . . 411
Processing files with multithreading . . . . . . 452
Performance considerations of static and
File definition storage . . . . . . . . . 452
dynamic calls . . . . . . . . . . . . 413
Recommended usage for file access . . . . . 453
Making both static and dynamic calls . . . . 414
Example: usage patterns of file input and
Examples: static and dynamic CALL statements 414
output with multithreading. . . . . . . . 453
Calling nested COBOL programs . . . . . . 416
Handling COBOL limitations with multithreading 454
Making recursive calls . . . . . . . . . . 419
Calling to and from object-oriented programs . . 419
Using procedure and function pointers . . . . . 420 Part 5. Developing object-oriented
Deciding which type of pointer to use . . . . 421 programs . . . . . . . . . . . . 457
Calling a C function pointer . . . . . . . 421
Calling to alternate entry points . . . . . . 421
Chapter 28. Writing object-oriented
Making programs reentrant . . . . . . . . 422
programs . . . . . . . . . . . . . 459
Example: accounts. . . . . . . . . . . . 460
Chapter 25. Sharing data . . . . . . 423
Subclasses . . . . . . . . . . . . . 461
Passing data . . . . . . . . . . . . . . 423
Defining a class . . . . . . . . . . . . 462
Describing arguments in the calling program 424
CLASS-ID paragraph for defining a class . . . 464
Describing parameters in the called program 425
REPOSITORY paragraph for defining a class 464
Testing for OMITTED arguments . . . . . . 425
WORKING-STORAGE SECTION for defining
Coding the LINKAGE SECTION . . . . . . . 425
class instance data . . . . . . . . . . . 466
Coding the PROCEDURE DIVISION for passing
Example: defining a class . . . . . . . . 467
arguments . . . . . . . . . . . . . . 426
Defining a class instance method . . . . . . . 467
Grouping data to be passed . . . . . . . 426
METHOD-ID paragraph for defining a class
Handling null-terminated strings . . . . . . 426
instance method . . . . . . . . . . . 468
Using pointers to process a chained list . . . 427
INPUT-OUTPUT SECTION for defining a class
Passing return code information . . . . . . . 430
instance method . . . . . . . . . . . 469
Understanding the RETURN-CODE special
DATA DIVISION for defining a class instance
register . . . . . . . . . . . . . . 430
method . . . . . . . . . . . . . . 469
Using PROCEDURE DIVISION RETURNING . .
PROCEDURE DIVISION for defining a class
.. . . . . . . . . . . . . . . . . 431
instance method . . . . . . . . . . . 470
Specifying CALL . . . RETURNING . . . . . 431
Overriding an instance method . . . . . . 471
Sharing data by using the EXTERNAL clause. . . 431
Overloading an instance method . . . . . . 472
Sharing files between programs (external files) . . 432
Coding attribute (get and set) methods . . . . 473
Example: using external files . . . . . . . 432
Example: defining a method . . . . . . . 474
Defining a client . . . . . . . . . . . . 475
Chapter 26. Creating a DLL or a DLL REPOSITORY paragraph for defining a client 477
application . . . . . . . . . . . . 437 DATA DIVISION for defining a client . . . . 478
Dynamic link libraries (DLLs) . . . . . . . . 437 Comparing and setting object references . . . 479
Compiling programs to create DLLs . . . . . . 438 Invoking methods (INVOKE) . . . . . . . 480
Linking DLLs . . . . . . . . . . . . . 439 Creating and initializing instances of classes . . 482
Example: sample JCL for a procedural DLL Freeing instances of classes . . . . . . . . 483
application . . . . . . . . . . . . . . 440 Example: defining a client . . . . . . . . 484
Prelinking certain DLLs . . . . . . . . . . 441 Defining a subclass . . . . . . . . . . . 484
Using CALL identifier with DLLs . . . . . . 441 CLASS-ID paragraph for defining a subclass 485
Search order for DLLs in HFS . . . . . . . 442 REPOSITORY paragraph for defining a subclass 486
Using DLL linkage and dynamic calls together . . 442 WORKING-STORAGE SECTION for defining
Using procedure or function pointers with DLLs 443 subclass instance data . . . . . . . . . 486
Calling DLLs from non-DLLs . . . . . . . 444 Defining a subclass instance method . . . . 487
Example: calling DLLs from non-DLLs . . . . 444 Example: defining a subclass (with methods) 487
Using COBOL DLLs with C/C++ programs . . . 446 Defining a factory section . . . . . . . . . 488
Contents ix
Example: Language Environment callable Calling from exit modules . . . . . . . . . 613
services . . . . . . . . . . . . . . 573 Processing of INEXIT. . . . . . . . . . . 613
Parameter list for INEXIT . . . . . . . . 613
Processing of LIBEXIT . . . . . . . . . . 614
Part 8. Appendixes . . . . . . . . 575
Processing of LIBEXIT with nested COPY
statements . . . . . . . . . . . . . 615
Appendix A. Intermediate results and Parameter list for LIBEXIT . . . . . . . . 616
arithmetic precision . . . . . . . . 577 Processing of PRTEXIT . . . . . . . . . . 617
Terminology used for intermediate results . . . . 578 Parameter list for PRTEXIT . . . . . . . . 617
Example: calculation of intermediate results . . . 579 Processing of ADEXIT . . . . . . . . . . 618
Fixed-point data and intermediate results . . . . 579 Parameter list for ADEXIT . . . . . . . . 619
Addition, subtraction, multiplication, and Error handling for exit modules . . . . . . . 619
division . . . . . . . . . . . . . . 579 Using the EXIT compiler option with CICS and
Exponentiation . . . . . . . . . . . . 580 SQL statements . . . . . . . . . . . . . 620
Example: exponentiation in fixed-point INEXIT . . . . . . . . . . . . . . 620
arithmetic . . . . . . . . . . . . . 581 LIBEXIT . . . . . . . . . . . . . . 620
Truncated intermediate results. . . . . . . 582 PRTEXIT . . . . . . . . . . . . . . 620
Binary data and intermediate results . . . . 582 ADEXIT . . . . . . . . . . . . . . 621
Intrinsic functions evaluated in fixed-point Example: INEXIT user exit . . . . . . . . . 621
arithmetic . . . . . . . . . . . . . . 583
Integer functions . . . . . . . . . . . 583 Appendix F. JNI.cpy . . . . . . . . 625
Mixed functions . . . . . . . . . . . 583
Floating-point data and intermediate results . . . 584
Appendix G. COBOL SYSADATA file
Exponentiations evaluated in floating-point
arithmetic . . . . . . . . . . . . . 585 contents . . . . . . . . . . . . . 631
Intrinsic functions evaluated in floating-point Existing compiler options affecting the SYSADATA
arithmetic . . . . . . . . . . . . . 585 file . . . . . . . . . . . . . . . . . 631
Arithmetic expressions in nonarithmetic statements 586 Record types . . . . . . . . . . . . . 632
Example: SYSADATA . . . . . . . . . . 633
SYSADATA record descriptions . . . . . . . 634
Appendix B. Complex OCCURS
Common header section . . . . . . . . . . 635
DEPENDING ON . . . . . . . . . . 587 Job identification record - X’0000’. . . . . . . 636
Example: complex ODO . . . . . . . . . . 587 ADATA identification record - X’0001’ . . . . . 637
How length is calculated . . . . . . . . 588 Compilation unit start/end record - X’0002’ . . . 637
Setting values of ODO objects . . . . . . . 588 Options record - X’0010’ . . . . . . . . . . 638
Effects of change in ODO object value . . . . . 588 External symbol record - X’0020’ . . . . . . . 647
Preventing index errors when changing ODO Parse tree record - X’0024’ . . . . . . . . . 648
object value . . . . . . . . . . . . . 589 Token record - X’0030’ . . . . . . . . . . 661
Preventing overlay when adding elements to a Source error record - X’0032’ . . . . . . . . 662
variable table . . . . . . . . . . . . 589 Source record - X’0038’ . . . . . . . . . . 662
COPY REPLACING record - X’0039’. . . . . . 663
Appendix C. Converting double-byte Symbol record - X’0042’ . . . . . . . . . . 664
character set (DBCS) data . . . . . . 593 Symbol cross-reference record - X’0044’ . . . . . 675
DBCS notation . . . . . . . . . . . . . 593 Nested program record - X’0046’ . . . . . . . 676
Alphanumeric to DBCS data conversion Library record - X’0060’ . . . . . . . . . . 677
(IGZCA2D) . . . . . . . . . . . . . . 593 Statistics record - X’0090’ . . . . . . . . . 678
IGZCA2D syntax . . . . . . . . . . . 593 EVENTS record - X’0120’ . . . . . . . . . 678
IGZCA2D return codes . . . . . . . . . 594
Example: IGZCA2D . . . . . . . . . . 595 Appendix H. Sample programs . . . . 679
DBCS to alphanumeric data conversion (IGZCD2A) 595 IGYTCARA: batch application . . . . . . . . 679
IGZCD2A syntax . . . . . . . . . . . 595 Input data for IGYTCARA . . . . . . . . 680
IGZCD2A return codes . . . . . . . . . 596 Report produced by IGYTCARA . . . . . . 681
Example: IGZCD2A . . . . . . . . . . 597 Preparing to run IGYTCARA . . . . . . . 682
IGYTCARB: interactive program . . . . . . . 683
Appendix D. XML reference material 599 Preparing to run IGYTCARB . . . . . . . 684
XML exceptions that allow continuation . . . . 599 IGYTSALE: nested program application . . . . 686
XML exceptions that do not allow continuation . . 603 Input data for IGYTSALE . . . . . . . . 687
XML conformance . . . . . . . . . . . . 606 Reports produced by IGYTSALE . . . . . . 689
Preparing to run IGYTSALE . . . . . . . 693
Appendix E. EXIT compiler option . . 611 Language elements and concepts that are
illustrated . . . . . . . . . . . . . . 694
Using the user-exit work area . . . . . . . . 612
x Programming Guide
Notices . . . . . . . . . . . . . . 699 Enterprise COBOL for z/OS and OS/390 . . . . 725
Trademarks . . . . . . . . . . . . . . 700 Related publications . . . . . . . . . . . 725
Contents xi
xii Programming Guide
About this document
Welcome to IBM Enterprise COBOL for z/OS and OS/390, IBM’s 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 usage of data in standardized formats, including
XML and Unicode
For a comparison of commonly used Enterprise COBOL and IBM z/OS Language
Environment terms, see “Comparison of commonly used terms” on page xiv.
Abbreviated terms
Certain terms are used in a shortened form in this document. Abbreviations for the
product names used most frequently are listed alphabetically in the following
table:
Other terms, if not commonly understood, are shown in italics the first time that
they appear, and are listed in the glossary at the back of this document.
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:
If choosing one of the items is optional, the entire stack appears below the main
path:
If one of the items is the default, it appears above the main path and the
remaining choices are shown below:
v An arrow returning to the left, above the main line, indicates an item that can be
repeated:
If the repeat arrow contains a comma, you must separate repeated items with a
comma:
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.
To more clearly separate some examples from the explanatory text, they are
presented in a monospace font.
Summary of changes
This section lists the key changes that have been made to Enterprise COBOL for
z/OS and OS/390. The changes that are discussed in this document have an
associated page reference for your convenience. The latest technical changes are
marked by a revision bar in the left margin.
| For further details about these enhancements to debugging support, see Debug
| Tool User’s Guide.
| v Extending Java interoperability to IMS: Object-oriented COBOL programs can
| run in an IMS Java dependent region. The object-oriented COBOL and Java
| languages can be mixed in a single application (“Using object-oriented COBOL
| and Java under IMS” on page 392).
| v Enhanced support for Java interoperability:
| – The OPTIMIZE compiler option is fully supported for programs that contain
| OO syntax for Java interoperability.
| – Object references of type jobjectArray are supported for interoperation
| between COBOL and Java (“Declaring arrays and strings for Java” on
| page 506).
| – OO applications that begin with a COBOL main factory method can be
| invoked with the java command (“Structuring OO applications” on page 498).
| – A new environment variable, COBJVMINITOPTIONS, is provided, enabling
| the user to specify options that will be used when COBOL initializes a Java
| virtual machine (JVM) (“Running OO applications under UNIX” on page 279).
| – OO applications that begin with a COBOL program can, with some
| limitations, be bound as modules in a PDSE and run using batch JCL
| (“Preparing and running OO applications using JCL or TSO/E” on page 282).
| v Unicode enhancement for working with DB2: The code pages for host variables
| are handled implicitly when you use the DB2 integrated coprocessor. SQL
| DECLARE statements are necessary only for variables described with USAGE
| DISPLAY or USAGE DISPLAY-1 when COBOL and DB2 code pages do not match
| (“Coding SQL statements” on page 385).
Be sure to include the name of the document, the publication number of the
document, the version of Enterprise COBOL, and, if applicable, the specific
location (for example, page number) 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 it believes appropriate without incurring any
obligation to you.
2 Programming Guide
Establishing record formats. . . . . . . . 120 Specifying relative organization for VSAM files 151
Logical records . . . . . . . . . . . 120 Fixed-length and variable-length RRDS . . . 152
Requesting fixed-length format . . . . . 121 Simulating variable-length RRDS . . . . . 152
Requesting variable-length format . . . . 122 Specifying access modes for VSAM files . . . 153
Requesting spanned format. . . . . . . 124 Example: using dynamic access with VSAM
Requesting undefined format . . . . . . 126 files . . . . . . . . . . . . . . 154
Setting block sizes . . . . . . . . . . . 127 Defining record lengths for VSAM files. . . . 154
Letting z/OS determine block size . . . . 127 Defining fixed-length records . . . . . . 154
Setting block size explicitly . . . . . . . 127 Defining variable-length records . . . . . 154
Taking advantage of LBI. . . . . . . . 128 Coding input and output statements for VSAM
Block size and the DCB RECFM files . . . . . . . . . . . . . . . . 155
subparameter . . . . . . . . . . . 129 File position indicator . . . . . . . . . 157
Coding input and output statements for QSAM Opening a file (ESDS, KSDS, or RRDS) . . . . 157
files . . . . . . . . . . . . . . . . 129 Opening an empty file . . . . . . . . 158
Opening QSAM files . . . . . . . . . . 130 Statements to load records into a VSAM file 159
Dynamically creating QSAM files with Opening a loaded file (a file with records) 159
CBLQDA . . . . . . . . . . . . . . 130 Reading records from a VSAM file . . . . . 159
Adding records to QSAM files. . . . . . . 131 Updating records in a VSAM file . . . . . . 160
Updating QSAM files . . . . . . . . . 131 Adding records to a VSAM file . . . . . . 161
Writing QSAM files to a printer or spooled data Adding records sequentially . . . . . . 161
set . . . . . . . . . . . . . . . . 131 Adding records randomly or dynamically 162
Controlling the page size . . . . . . . 132 Replacing records in a VSAM file. . . . . . 162
Controlling the vertical positioning of records 132 Deleting records from a VSAM file . . . . . 162
Closing QSAM files . . . . . . . . . . 132 Closing VSAM files . . . . . . . . . . 162
Handling errors in QSAM files . . . . . . . 133 Handling errors in VSAM files . . . . . . . 163
Working with QSAM files . . . . . . . . . 133 Protecting VSAM files with a password . . . . 164
Defining and allocating QSAM files . . . . . 134 Example: password protection for a VSAM
Parameters for creating QSAM files . . . . 135 indexed file . . . . . . . . . . . . . 164
Retrieving QSAM files . . . . . . . . . 136 Working with VSAM data sets under z/OS and
Parameters for retrieving QSAM files . . . 136 UNIX . . . . . . . . . . . . . . . . 165
Ensuring file attributes match your program 137 Defining VSAM files . . . . . . . . . . 165
Processing existing files . . . . . . . . 137 Creating alternate indexes . . . . . . . . 166
Defining variable-length (format-V) records 137 Example: entries for alternate indexes . . . 168
Defining format-U records . . . . . . . 138 Allocating VSAM files . . . . . . . . . 168
Defining fixed-length records . . . . . . 138 Sharing VSAM files through RLS . . . . . . 170
Processing new files . . . . . . . . . 138 Preventing update problems with VSAM files
Processing files dynamically created by in RLS mode . . . . . . . . . . . 170
COBOL . . . . . . . . . . . . . 139 Restrictions when using RLS . . . . . . 170
Using striped extended-format QSAM data sets 139 Handling errors in VSAM files in RLS mode 171
Allocation of buffers for QSAM files. . . . 140 Improving VSAM performance . . . . . . . 171
Accessing HFS files using QSAM . . . . . . . 140
Labels for QSAM files . . . . . . . . . . 141 Chapter 11. Processing line-sequential files . . 173
Using trailer and header labels . . . . . . 141 Defining line-sequential files and records in
Getting a user-label track . . . . . . . 142 COBOL . . . . . . . . . . . . . . . 173
Handling user labels . . . . . . . . . 142 Allowable control characters . . . . . . . 174
Format of standard labels . . . . . . . . 143 Describing the structure of a line-sequential file 174
Standard user labels . . . . . . . . . 143 Defining and allocating line-sequential files . . . 175
Processing QSAM ASCII files on tape . . . . . 143 Coding input-output statements for line-sequential
Requesting the ASCII alphabet . . . . . . 144 files . . . . . . . . . . . . . . . . 175
Defining the record formats . . . . . . . 144 Opening line-sequential files . . . . . . . 176
Defining the ddname . . . . . . . . . . 144 Reading records from line-sequential files . . . 176
Processing ASCII file labels . . . . . . . . . 145 Adding records to line-sequential files . . . . 177
Closing line-sequential files. . . . . . . . 177
Chapter 10. Processing VSAM files . . . . . 147 Handling errors in line-sequential files . . . . . 178
VSAM files . . . . . . . . . . . . . . 148
Defining VSAM file organization and records . . 149 Chapter 12. Sorting and merging files . . . . 179
Specifying sequential organization for VSAM Sort and merge process . . . . . . . . . . 180
files . . . . . . . . . . . . . . . 150 Describing the sort or merge file . . . . . . . 180
Specifying indexed organization for VSAM files 150 Describing the input to sorting or merging . . . 181
Alternate keys . . . . . . . . . . . 151 Example: describing sort and input files for
Alternate index . . . . . . . . . . . 151 SORT . . . . . . . . . . . . . . . 181
4 Programming Guide
Chapter 1. Structuring your program
A COBOL program consists of four divisions, each with a specific logical function:
v IDENTIFICATION DIVISION
v ENVIRONMENT DIVISION
v DATA DIVISION
v PROCEDURE DIVISION
To define a COBOL class or method, you need to define some divisions differently
than you would for a program.
RELATED TASKS
“Identifying a program”
“Describing the computing environment” on page 7
“Describing the data” on page 12
“Processing the data” on page 17
“Defining a class” on page 462
“Defining a class instance method” on page 467
“Structuring OO applications” on page 498
Identifying a program
Use the IDENTIFICATION DIVISION to name your program and, if you want, give
other identifying information.
You can use the optional AUTHOR, INSTALLATION, DATE-WRITTEN, and DATE-COMPILED
paragraphs for descriptive information about your program. The data you enter on
the DATE-COMPILED paragraph is replaced with the latest compilation date.
IDENTIFICATION DIVISION.
Program-ID. Helloprog.
Author. A. Programmer.
Installation. Computing Laboratories.
Date-Written. 08/21/2002.
Date-Compiled. 08/21/2002.
Use the PROGRAM-ID paragraph to name your program. The program name that you
assign is used in these ways:
v Other programs use the name to call your program.
v The name appears in the header on each page, except the first page, of the
program listing generated when the program is compiled.
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 created
by the compilation.
Tip: Do not use program names that start with prefixes used by IBM products. If
you try to use programs whose names start with any of the following, your CALL
statements might resolve to IBM library or compiler routines rather than to your
intended program:
Tip: When the program name is case sensitive, avoid mismatches with the name
the compiler is looking for. Verify that the appropriate setting of the PGMNAME
compiler option is used.
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”
RELATED REFERENCES
Compiler limits (Enterprise COBOL Language Reference)
Conventions for program names (Enterprise COBOL Language Reference)
You can code RECURSIVE only on the outermost program of a compilation unit.
Neither nested subprograms nor programs containing 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 17
“Making recursive calls” on page 419
RELATED CONCEPTS
“Nested programs” on page 416
6 Programming Guide
Changing the header of a source listing
The header on the first page of your source statement listing contains the
identification of the compiler and the current release level, plus the date and time
of compilation and the page number. For example:
PP 5655-G53 IBM Enterprise COBOL for z/OS and OS/390 3.2.0 Date 08/21/2002 Time 15:05:19 Page 1
You can customize the header on succeeding pages of the listing with the
compiler-directing TITLE statement.
RELATED REFERENCES
TITLE statement (Enterprise COBOL Language Reference)
RELATED TASKS
“Specifying the collating sequence” on page 8
“Defining symbolic characters” on page 9
“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)
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 program’s 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 file’s 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 119
Chapter 10, “Processing VSAM files” on page 147
Chapter 11, “Processing line-sequential files” on page 173
“Describing the computing environment” on page 7
The sequence that you use can be based on one of these alphabets:
v EBCDIC (use NATIVE if the native character set is EBCDIC), the default if you
omit the ALPHABET clause
v ASCII (use STANDARD-1)
v ISO 7-bit code, International Reference Version (use STANDARD-2)
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 operands.
8 Programming Guide
RELATED TASKS
“Choosing alternate collating sequences” on page 188
“Comparing national data items” on page 110
Source-Computer. IBM-390.
Object-Computer. IBM-390.
RELATED TASKS
“Specifying the collating sequence” on page 8
The class-name can be referenced only in a class condition. This user-defined class
is not the same as an object-oriented class.
The following shows 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)),
// DCB=(BLKSIZE=400)
/*
. . .
v Environment variable (export command):
(1)
export OUTFILE=DSNAME(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 ddname in the DD statement or the environment variable name in the
export command, corresponds to the assignment-name in the ASSIGN clause:
v //OUTFILE DD DSNAME=OUT171 . . ., or
v export OUTFILE= . . .
10 Programming Guide
SELECT CARPOOL
. . .
FD CARPOOL
RELATED TASKS
“Optimizing buffer and device space” on page 12
Rules for using different files: The name 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. You can change the actual file by
using the DSNAME in the DD statement or the DSNAME or path name in the
environment variable.
The file-name that you use with 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
is directed to SYSOUT, do not use SYSOUT as the ddname or environment variable
name on the SELECT clause for a file.
Example: using different input files: Consider a COBOL program that is used in
exactly the same way for several different master files. It contains this SELECT
clause:
SELECT MASTER
ASSIGN TO DA-3330-S-MASTERA
Assume the three possible input files are MASTER1, MASTER2, and MASTER3. You must
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, prior to running 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 MASTERA will therefore be a reference to the file
currently assigned to 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.
The APPLY WRITE-ONLY clause has meaning only for sequential files that have
variable-length records and are blocked.
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 292
The Enterprise COBOL compiler limits the maximum size of DATA DIVISION
elements.
RELATED CONCEPTS
“Comparison of WORKING-STORAGE and LOCAL-STORAGE” on page 14
RELATED TASKS
“Using data in input and output operations”
“Using data from another program” on page 16
RELATED REFERENCES
Compiler limits (Enterprise COBOL Language Reference)
12 Programming Guide
v In the record description following 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
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 then 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, 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 416
RELATED TASKS
“Sharing files between programs (external files)” on page 432
RELATED REFERENCES
“FILE SECTION entries”
RELATED CONCEPTS
“Labels for QSAM files” on page 141
14 Programming Guide
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.
| See the related tasks for information about WORKING-STORAGE in COBOL class
| definitions.
RELATED TASKS
“WORKING-STORAGE SECTION for defining class instance data” on page 466
Chapter 27, “Preparing COBOL programs for multithreading” on page 449
“Ending and reentering main programs or subprograms” on page 408
RELATED REFERENCES
Working-Storage section (Enterprise COBOL Language Reference)
Local-Storage section (Enterprise COBOL Language Reference)
if numb = 0
move 1 to fact
else
subtract 1 from numb
call ’factorial’
multiply num by fact
end-if.
The following tables show the changing values of the data items in LOCAL-STORAGE
(L-S) and WORKING-STORAGE (W-S) 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 4 5
___________________________________
L-S num 5 4 3 2 1 0
___________________________________
W-S numb 5 4 3 2 1 0
fact 0 0 0 0 0 0
___________________________________
Recursive
GOBACKs: 5 4 3 2 1 Main
____________________________________
L-S num 0 1 2 3 4 5
____________________________________
W-S numb 0 0 0 0 0 0
fact 1 1 2 6 24 120
____________________________________
RELATED CONCEPTS
“Comparison of WORKING-STORAGE and LOCAL-STORAGE” on page 14
RELATED TASKS
“Sharing data in separately compiled programs”
“Sharing data in nested programs”
RELATED TASKS
“Passing data” on page 423
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 416
16 Programming Guide
Sharing data in recursive or multithreaded programs
If you compile your program as RECURSIVE or with the THREAD compiler option,
data that is defined in the LINKAGE SECTION is not accessible on subsequent
invocations of the program.
If you compile your program as RECURSIVE or 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 449
RELATED TASKS
“Making recursive calls” on page 419
“Processing files with multithreading” on page 452
RELATED REFERENCES
SET statement (Enterprise COBOL Language Reference)
“THREAD” on page 325
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 your division header to receive parameters with the USING phrase or
to return a value with the RETURNING phrase.
To receive a parameter that was passed by value, code the division header for a
program as follows:
PROCEDURE DIVISION USING BY VALUE dataname
You can also combine USING and RETURNING in a PROCEDURE DIVISION header:
Be sure to define dataname and dataname2 in the LINKAGE SECTION of the DATA
DIVISION.
RELATED CONCEPTS
“How logic is divided in the PROCEDURE DIVISION”
RELATED TASKS
“Eliminating repetitive coding” on page 569
RELATED CONCEPTS
“Compiler-directing statements” on page 20
“Scope terminators” on page 20
“Imperative statements” on page 19
“Conditional statements” on page 19
“Declaratives” on page 21
RELATED REFERENCES
PROCEDURE DIVISION structure (Enterprise COBOL Language Reference)
18 Programming Guide
Imperative statements
An imperative statement indicates an unconditional action to be taken (such as
ADD, MOVE, INVOKE, or CLOSE).
RELATED CONCEPTS
“Conditional statements”
“Scope terminators” on page 20
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).
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
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.
RELATED CONCEPTS
“Imperative statements” on page 19
“Scope terminators”
RELATED TASKS
“Selecting program actions” on page 75
RELATED REFERENCES
Conditional statements (Enterprise COBOL Language Reference)
Compiler-directing statements
A compiler-directing statement is not part of the program logic. A
compiler-directing statement causes the compiler to take specific action about the
program structure, COPY processing, listing control, or control flow.
RELATED REFERENCES
“Compiler-directing statements” on page 332
Compiler-directing statements (Enterprise COBOL Language Reference)
Scope terminators
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.
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 program’s logic. Explicit
scope terminators make a program easier to understand and prevent unintentional
20 Programming Guide
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.
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 19
“Imperative statements” on page 19
Declaratives
Declaratives provide one or more special-purpose sections that are executed when
an exception condition occurs.
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 339
RELATED REFERENCES
Declaratives (Enterprise COBOL Language Reference)
RELATED CONCEPTS
“Storage and its addressability” on page 33
RELATED TASKS
“Using variables, structures, literals, and constants”
“Assigning values to data items” on page 25
“Displaying values on a screen or in a file (DISPLAY)” on page 30
“Using intrinsic functions (built-in functions)” on page 32
“Using tables (arrays) and pointers” on page 33
Chapter 7, “Coding for run-time use of national languages” on page 103
Variables
A variable is a data item; its value can change during a program. The values are
restricted, however, to the data type that you define when you give the variable a
name and a length. For example, if a customer name is a variable in your program,
you could code:
Data Division.
. . .
01 Customer-Name Pic X(20).
01 Original-Customer-Name Pic X(20).
. . .
Procedure Division.
. . .
Move Customer-Name to Original-Customer-Name
. . .
Literals
A literal is a character string whose value is given by the characters themselves.
When you know the value you want to use for a data item, use a literal
representation of the data value in the PROCEDURE DIVISION. You do not need to
define it or refer to a data-name. For example, you can prepare an error message
for an output file this way:
Move “Name is not valid” To Customer-Name
Constants
A constant is a data item that has only one value. COBOL does not define a
construct specifically for constants. However, most COBOL programmers define a
data item with an initial VALUE (as opposed to initializing a variable using the
INITIALIZE statement). For example:
Data Division.
. . .
01 Report-Header pic x(50) value “Company Sales Report”.
. . .
01 Interest pic 9v9999 value 1.0265.
Figurative constants
Certain commonly used constants and literals are provided as reserved words
called figurative constants: ZERO, SPACE, HIGH-VALUE, LOW-VALUE, QUOTE, NULL, and ALL.
Because they represent fixed values, figurative constants do not require a data
definition. For example:
24 Programming Guide
Move Spaces To Report-Header
RELATED REFERENCES
PICTURE clause (Enterprise COBOL Language Reference)
Literals (Enterprise COBOL Language Reference)
Figurative constants (Enterprise COBOL Language Reference)
RELATED TASKS
“Initializing a structure (INITIALIZE)” on page 27
“Assigning values to variables or structures (MOVE)” on page 27
“Joining data items (STRING)” on page 87
“Splitting data items (UNSTRING)” on page 89
“Assigning arithmetic results (MOVE or COMPUTE)” on page 28
“Tallying and replacing data items (INSPECT)” on page 95
“Assigning input from a screen or file (ACCEPT)” on page 29
“Displaying values on a screen or in a file (DISPLAY)” on page 30
Chapter 7, “Coding for run-time use of national languages” on page 103
26 Programming Guide
RELATED TASKS
“Initializing a structure (INITIALIZE)”
The following example shows how you can reset fields in a transaction record
produced by a program to spaces and zeros. The fields are not identical in each
record produced.
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
For example, the following statement assigns the contents of the variable
Customer-Name to the variable Orig-Customer-Name:
Move Customer-Name to Orig-Customer-Name
When you move a group item to another group item, be sure the subordinate data
descriptions are compatible. The compiler performs all MOVE statements regardless
of whether the items fit, even if a destructive overlap could occur at run time.
For variables that contain numbers, moves can be more complicated because there
are several ways numbers are represented. In general, the algebraic values of
numbers are moved if possible (as opposed to the digit-by-digit move performed
with character data):
This move would result in Item-x containing the value 3.0, represented by 0030.
You can move an alphanumeric item or an integer item to a national variable; the
item is converted. You can move a national item only to another national variable.
In either case padding or truncation might occur, and you must ensure that
truncation does not occur within a character.
The following example shows a data item in the Greek language that moves into 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 encoding of language characters” on page 105
RELATED REFERENCES
MOVE statement (Enterprise COBOL Language Reference)
“CODEPAGE” on page 294
“Converting national data” on page 107
The MOVE statement carries out the assignment with truncation. You can, however,
specify the DIAGTRUNC compiler option to request that the compiler issue a warning
diagnostic 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.
When 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 the ON SIZE ERROR phrase is not specified, 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 variable. For example:
Compute z = y + (x ** 3)
Compute x = Function Max(x y z)
28 Programming Guide
statement, and the values they return are passed in the parameters in the CALL
statement. For example, you can call the Language Environment service CEESIABS
to find the absolute value of a variable with the statement:
Call ’CEESIABS’ Using Arg, Feedback-code, Result.
As a result of this call, the variable Result is assigned to be the absolute value of
the value that is in the variable Arg; the variable Feedback-code contains the return
code indicating whether the service completed successfully. You have to define all
the variables in the Data Division using the correct descriptions, according to the
requirements of the particular callable service you are using. For the example
above, the variables could be defined like this:
77 Arg Pic s9(9) Binary.
77 Feedback-code Pic x(12) Display.
77 Result Pic s9(9) Binary.
RELATED REFERENCES
“DIAGTRUNC” on page 298
Intrinsic functions (Enterprise COBOL Language Reference)
Callable services (Language Environment Programming Reference)
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
Note that device can be a ddname that references a hierarchical file system (HFS)
path. If this DD is not defined and your program is running in a UNIX
environment, stdin is the input source. If this DD is not defined and your
program is not running in a UNIX environment, the ACCEPT statement fails.
When you assign a value to a national data item, input data from the console is
converted from EBCDIC to Unicode representation (UTF-16), based on the value of
the CODEPAGE option. This is the only situation where conversion of national data is
done when you use the ACCEPT statement, because the input is known to be
coming from a screen.
If you want conversion done when the input data is from any other device, use the
NATIONAL-OF intrinsic function.
RELATED CONCEPTS
“Unicode and encoding of language characters” on page 105
To write data to a destination other than the system logical output device, use the
UPON clause 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 hierarchical file system (HFS) with this ddname. For
example, with the following definition, your DISPLAY output is written to the HFS
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 national data item to the console, it is converted
from Unicode representation (UTF-16) to EBCDIC, based on the value of the
CODEPAGE option. This is the only situation where conversion of national data is
done when you use the DISPLAY statement, because the output is known to be
directed to a screen.
If you want a national data item to be converted when you direct output to a
different device, use the DISPLAY-OF intrinsic function, such as in this example:
01 Data-in-Unicode pic N(10) usage national.
. . .
Display function Display-of(Data-in-Unicode, 00037)
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 (HFS) with this
ddname.
If the OUTDD ddname is not allocated and you are not running in a UNIX
environment, a default DD of SYSOUT=* is allocated.
30 Programming Guide
If the OUTDD ddname is not allocated and you are running in a 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; rather the output is written as a single stream of characters without
line breaks.
If OUTDD and the Language Environment run-time option MSGFILE both specify the
same ddname, DISPLAY output and Language Environment run-time diagnostics
are both routed to the Language Environment message file.
If you specify the WITH NO ADVANCING phrase and the output is going to stdout or
stderr, a new-line 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.
For example:
DISPLAY “ABC”
DISPLAY “CDEF” WITH NO ADVANCING
DISPLAY “GHIJK” WITH NO ADVANCING
DISPLAY “LMNOPQ”
DISPLAY “RSTUVWX”
If you use the statements above, the result sent to the output device is:
ABC
CDEF
+GHIJK
+LMNOPQ
RSTUVMX
The output 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 new-line character is appended to the end of the stream.
RELATED CONCEPTS
“Unicode and encoding of language characters” on page 105
RELATED REFERENCES
DISPLAY statement (Enterprise COBOL Language Reference)
“OUTDD” on page 313
“CODEPAGE” on page 294
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 having 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 variable.
For example, you could use Sqrt to invoke an intrinsic function and to name a
variable 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.
. . .
Compute Sqrt = 16 ** .5
Compute z = x + Function Sqrt(y)
. . .
32 Programming Guide
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.
Nesting functions
Functions can reference other functions as arguments as long as the results of the
nested functions meet the requirements for the arguments of the outer function.
For example:
Compute x = Function Max((Function Sqrt(5)) 2.5 3.5)
In this case, Function Sqrt(5) returns a numeric value. Thus, the three arguments
to the MAX function are all numeric, which is an allowable argument type for this
function.
RELATED TASKS
“Processing table items using intrinsic functions” on page 73
“Converting data items (intrinsic functions)” on page 96
“Evaluating data items (intrinsic functions)” on page 99
Pointers are data items that contain virtual storage addresses. You define them
explicitly with the USAGE IS POINTER clause in the DATA DIVISION or implicitly as
ADDRESS OF special registers.
RELATED TASKS
“Defining a table (OCCURS)” on page 59
“Using procedure and function pointers” on page 420
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 run-time
options influence the AMODE and RMODE attributes of your program and data, alone
and in combination:
DATA Compiler option that influences the location of storage for working-storage
data, I-O buffers, and parameter lists.
RMODE Compiler option that influences the residency mode.
RENT Compiler option to generate a reentrant program and that influences the
location of storage and the residency mode of your program.
HEAP Run-time option that controls storage for the run-time heap. For example,
COBOL working storage is allocated from heap storage.
STACK Run-time option that controls storage for the run-time stack. For example,
COBOL local storage is allocated from stack storage.
ALL31 Run-time option that specifies whether an application can run entirely in
AMODE 31.
34 Programming Guide
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.
When you specify the run-time option HEAP(,,BELOW), the DATA compiler option has
no effect; the storage for LOCAL-STORAGE SECTION data areas is allocated from below
the 16-MB line. However, with HEAP(,,ANYWHERE) as the run-time 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.
In all other cases, the storage for EXTERNAL data will be obtained from below the
16-MB line. When you specify the ALL31(ON) run-time option, all the programs in
the run unit must be capable of running in 31-bit addressing mode.
RELATED CONCEPTS
AMODE considerations for heap storage (Language Environment Programming Guide)
RELATED REFERENCES
“Allocation of buffers for QSAM files” on page 140
“DATA” on page 296
“RENT” on page 316
“RMODE” on page 317
“Performance-related compiler options” on page 563
HEAP (Language Environment Programming Reference)
STACK (Language Environment Programming Reference)
ALL31 (Language Environment Programming Reference)
z/OS DFSMS: Program Management
36 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.
This section describes how 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 38
“Controlling how numeric data is stored” on page 39
“Checking for incompatible data (numeric class test)” on page 46
“Performing arithmetic” on page 47
“Using currency signs” on page 55
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.
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
However, if you plan to port your program or data to a different machine, you
might want to code the sign as a separate position in storage. In this 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 data items that will be printed or displayed.
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 a
floating-point literal:
05 Compute-result Usage Comp-2 Value 06.23E-24.
RELATED CONCEPTS
Appendix A, “Intermediate results and arithmetic precision” on page 577
RELATED TASKS
“Displaying numeric data”
“Controlling how numeric data is stored” on page 39
“Performing arithmetic” on page 47
RELATED REFERENCES
“Sign representation and processing” on page 45
“ARITH” on page 291
“NUMPROC” on page 310
If the contents of Price are 0150099 (representing the value 1,500.99), then
$ 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.
38 Programming Guide
You can move numeric-edited items to numeric or numeric-edited items. In the
following example, the value of the numeric-edited item is moved to the numeric
item:
Move Edited-price to Price
Display Price
RELATED TASKS
“Controlling how numeric data is stored”
“Defining numeric data” on page 37
“Performing arithmetic” on page 47
RELATED REFERENCES
MOVE statement (Enterprise COBOL Language Reference)
The numeric data you use in your program will have one of the following formats
available with COBOL:
v External decimal (USAGE DISPLAY)
v External floating point (USAGE DISPLAY)
v Internal decimal (USAGE PACKED-DECIMAL)
v Binary (USAGE BINARY)
v Native binary (USAGE COMP-5)
v Internal floating point (USAGE COMP-1, USAGE COMP-2)
COMP and COMP-4 are synonymous with BINARY, and COMP-3 is synonymous with
PACKED-DECIMAL.
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 floating-point data, for which you cannot use a PICTURE
clause).
RELATED CONCEPTS
“Formats for numeric data”
“Data format conversions” on page 43
Appendix A, “Intermediate results and arithmetic precision” on page 577
RELATED TASKS
“Defining numeric data” on page 37
“Displaying numeric data” on page 38
“Performing arithmetic” on page 47
RELATED REFERENCES
“Conversions and precision” on page 44
“Sign representation and processing” on page 45
External decimal (also known as zoned decimal) items are primarily intended for
receiving and sending numbers between your program and 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, COBOL’s computational numeric types
might be a better choice for the data items used in the arithmetic.
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.
40 Programming Guide
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.
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.
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 originating in non-COBOL
programs where the data might not conform to a COBOL PICTURE clause.
The table below shows the ranges of values possible for COMP-5 data items.
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).
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.
COMP-1 and COMP-2 data items are stored in z900 hexadecimal format.
RELATED CONCEPTS
Appendix A, “Intermediate results and arithmetic precision” on page 577
RELATED REFERENCE
VALUE clause (Enterprise COBOL Language Reference)
“TRUNC” on page 326
42 Programming Guide
PICTURE and USAGE and
Numeric type optional SIGN clause Value Internal representation
Binary PIC S9999 BINARY + 1234 04 D2
COMP - 1234 FB 2E
COMP-4
COMP-5 + 123451 30 39
- 123451 CF C7
PIC 9999 BINARY 1234 04 D2
COMP
COMP-4
COMP-5 600001 EA 60
Internal PIC S9999 PACKED-DECIMAL + 1234 01 23 4C
decimal COMP-3 - 1234 01 23 4D
PIC 9999 PACKED-DECIMAL + 1234 01 23 4F
COMP-3 - 1234 01 23 4F
Internal COMP-1 + 1234 43 4D 20 00
floating
point
Internal COMP-2 + 1234 43 4D 20 00 00 00 00 00
floating - 1234 C3 4D 20 00 00 00 00 00
point
External PIC +9(2).9(2)E+99 DISPLAY + 1234 4E F1 F2 4B F3
floating F4 C5 4E F0 F2
point
- 1234 60 F1 F2 4B F3
F4 C5 4E F0 F2
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.
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 with the same rules that are used for MOVE and COMPUTE
statements.
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.
RELATED REFERENCES
“Conversions and precision”
“Sign representation and processing” on page 45
When the compiler converts short form to long form for comparisons, zeros are
used for padding the shorter number.
When a USAGE COMP-1 data item is moved to a fixed-point data item with more
than nine digits, the fixed-point data item will receive only nine significant digits,
and the remaining digits will be zero.
When a USAGE COMP-2 data item is moved to a fixed-point data item with more
than 18 digits, the fixed-point data item will receive only 18 significant digits, and
the remaining digits will be zero.
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 with 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 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.
44 Programming Guide
RELATED CONCEPTS
Appendix A, “Intermediate results and arithmetic precision” on page 577
Given X’sd’, where s is the sign representation and d represents the digit, the valid
sign representations for external decimal (USAGE DISPLAY 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 external decimal
and internal decimal data. NUMPROC has no effect on binary data or floating-point
data.
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.
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 and OS/390.
RELATED REFERENCES
“NUMPROC” on page 310
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 both cases, the
receiving fields contain invalid data. Ensure that the contents of a data item
conform to its PICTURE and USAGE clauses before using the data item in any further
processing steps.
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”
The numeric class test checks the contents of a data item against a set of values
that are valid for the particular PICTURE and USAGE of the data item. For example, a
packed-decimal item is checked for hexadecimal values X’0’ through X’9’ in the
digit positions, and for a valid sign value in the sign position (whether separate or
nonseparate).
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.
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.
46 Programming Guide
RELATED REFERENCES
“NUMPROC” on page 310
Performing arithmetic
You can use any of several COBOL language features to perform arithmetic:
v “COMPUTE and other arithmetic statements”
v “Arithmetic expressions”
v “Numeric intrinsic functions” on page 48
v “Math and date Language Environment services” on page 49
Some arithmetic might be more intuitive using arithmetic statements other than
COMPUTE. For example:
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.
RELATED CONCEPTS
“Fixed-point versus floating-point arithmetic” on page 53
Appendix A, “Intermediate results and arithmetic precision” on page 577
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. . .
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, necessary or not, make your program easier to read.
RELATED CONCEPTS
“Fixed-point versus floating-point arithmetic” on page 53
Appendix A, “Intermediate results and arithmetic precision” on page 577
Numeric intrinsic functions return a signed numeric value. They are treated as
temporary numeric data items.
You can use intrinsic functions to perform several different arithmetic operations,
as outlined in the following table.
48 Programming Guide
Number handling Date and time Finance Mathematics Statistics
LENGTH CURRENT-DATE ANNUITY ACOS MEAN
MAX DATE-OF-INTEGER PRESENT-VALUE ASIN MEDIAN
MIN DATE-TO-YYYYMMDD ATAN MIDRANGE
NUMVAL DATEVAL COS RANDOM
NUMVAL-C DAY-OF-INTEGER FACTORIAL RANGE
ORD-MAX DAY-TO-YYYYDDD INTEGER STANDARD-DEVIATION
ORD-MIN INTEGER-OF-DATE INTEGER-PART VARIANCE
INTEGER-OF-DAY LOG
UNDATE LOG10
WHEN-COMPILED MOD
YEAR-TO-YYYY REM
YEARWINDOW SIN
SQRT
SUM
TAN
In this example, there are only three function arguments: a, b, and the arithmetic
expression (c / d).
You can use the integer special registers as arguments wherever integer arguments
are allowed.
RELATED CONCEPTS
“Fixed-point versus floating-point arithmetic” on page 53
Appendix A, “Intermediate results and arithmetic precision” on page 577
RELATED REFERENCES
“ARITH” on page 291
So for example (considering the first row of the table), 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.
1. RANDOM returns a long (64-bit) floating-point result even if you pass it a 31-digit argument and compile using
option 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 required by
that service (generally COMP-1 or COMP-2).
50 Programming Guide
This means that if you use INTDATE(LILIAN), you get equivalent results from
COBOL intrinsic functions and Language Environment callable date services.
RELATED CONCEPTS
“Fixed-point versus floating-point arithmetic” on page 53
Appendix A, “Intermediate results and arithmetic precision” on page 577
RELATED TASKS
“Using Language Environment callable services” on page 571
RELATED REFERENCES
“ARITH” on page 291
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.
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 Loan Pic 9(9)V99.
01 Payment Pic 9(9)V99.
01 Interest Pic 9(9)V99.
01 Number-Periods Pic 99.
. . .
Compute Loan = 15000
Compute Interest = .12
Compute Number-Periods = 36
Compute Payment =
Loan * Function Annuity((Interest / 12) Number-Periods)
52 Programming Guide
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 Tax-S Pic 99v999 value .045.
01 Tax-T Pic 99v999 value .02.
01 Tax-W Pic 99v999 value .035.
01 Tax-B Pic 99v999 value .03.
01 Ave-Tax Pic 99v999.
01 Median-Tax Pic 99v999.
01 Tax-Range Pic 99v999.
. . .
Compute Ave-Tax = Function Mean (Tax-S Tax-T Tax-W Tax-B)
Compute Median-Tax = Function Median (Tax-S Tax-T Tax-W Tax-B)
Compute Tax-Range = Function Range (Tax-S Tax-T Tax-W Tax-B)
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 data item defined as USAGE COMP-1, USAGE COMP-2, or external floating
point (USAGE DISPLAY 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
is true:
– An argument in an arithmetic expression results in floating point.
Fixed-point evaluations
In general, if an arithmetic operation contains neither of the characteristics listed
above for floating point, the compiler will cause 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.
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 another’s attributes, and then are
compared to each other.
evaluate (a + d)
when (b + e) thru c
when (f / g) thru (h * i)
. . .
end-evaluate
54 Programming Guide
RELATED REFERENCES
“Arithmetic expressions in nonarithmetic statements” on page 586
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 the 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.
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.
Modified
Code page Applicable countries from Euro sign
IBM-1140 USA, Canada, Netherlands, Portugal, IBM-037 X’9F’
Australia, New Zealand
IBM-1141 Austria, Germany IBM-273 X’9F’
IBM-1142 Denmark, Norway IBM-277 X’5A’
IBM-1143 Finland, Sweden IBM-278 X’5A’
IBM-1144 Italy IBM-280 X’9F’
IBM-1145 Spain, Latin America - Spanish IBM-284 X’9F’
IBM-1146 UK IBM-285 X’9F’
IBM-1147 France IBM-297 X’9F’
IBM-1148 Belgium, Canada, Switzerland IBM-500 X’9F’
IBM-1149 Iceland IBM-871 X’9F’
56 Programming Guide
On Size Error
Perform Conversion-Error
Not On Size Error
Move Deposit-in-FRF 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 FRF”
Display “Euro value: ” Report-in-Euro.
The exchange rate used in this example is for illustrative purposes only.
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 define repetitious items as separate, consecutive entries in the DATA
DIVISION, you can 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
“Defining a table (OCCURS)”
“Referring to an item in a table” on page 61
“Putting values into a table” on page 64
“Nesting tables” on page 60
“Creating variable-length tables (DEPENDING ON)” on page 68
“Searching a table” on page 71
“Processing table items using intrinsic functions” on page 73
“Handling tables efficiently” on page 557
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.
RELATED TASKS
“Creating variable-length tables (DEPENDING ON)” on page 68
“Nesting tables”
“Putting values into a table” on page 64
“Referring to an item in a table” on page 61
“Searching a table” on page 71
RELATED REFERENCES
OCCURS clause (Enterprise COBOL Language Reference)
Nesting tables
To create a two-dimensional table, define a one-dimensional table in each
occurrence of another one-dimensional table. For example:
Subscripting
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.
60 Programming Guide
The following valid references to SAMPLE-TABLE-THREE 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.
Indexing
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).
RELATED TASKS
“Defining a table (OCCURS)” on page 59
“Referring to an item in a table”
“Putting values into a table” on page 64
“Creating variable-length tables (DEPENDING ON)” on page 68
“Searching a table” on page 71
“Processing table items using intrinsic functions” on page 73
“Handling tables efficiently” on page 557
RELATED REFERENCES
OCCURS clause (Enterprise COBOL Language Reference)
RELATED TASKS
“Indexing” on page 63
“Subscripting”
Subscripting
The lowest possible subscript value is 1, which points to the first occurrence of the
table element. In a one-dimensional table, the subscript corresponds to the row
number.
If a data item with 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 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 change part of a table element rather than the whole element. Simply refer
to the character position and length of the substring to be changed within the
subscripted element. 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 moves the value ?? into table element number 1, beginning at
character position 3, for a length of 2:
RELATED TASKS
“Indexing” on page 63
62 Programming Guide
“Putting values into a table” on page 64
“Searching a table” on page 71
“Handling tables efficiently” on page 557
Indexing
You can create an index either with a particular table (using OCCURS INDEXED BY) or
separately (using USAGE IS INDEX).
For example:
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 this index to index another table only if both table descriptions have
the same number of table elements, and the table elements are the same length.
If you use USAGE IS INDEX to create an index, you can use the index data item with
any table. For example:
77 INX-B USAGE IS INDEX.
. . .
PERFORM VARYING INX-B FROM 1 BY 1 UNTIL INX-B > 10
DISPLAY TABLE-ITEM (INX-B)
. . .
END-PERFORM.
INX-B is used to traverse table TABLE-ITEM above, but could be used to traverse
other tables also.
Initialize the index-name with a SET, PERFORM VARYING, or SEARCH ALL statement.
You can then also use it in SEARCH or relational condition statements. To change the
value, use a PERFORM, SEARCH, or SET statement.
Use the SET statement to assign to an index the value that you stored in the index
data item defined by USAGE IS INDEX. For example, when you load records into a
variable-length table, you can store the index value of the last record read in 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 the table.
Because you are comparing a physical displacement, you can use index data items
only in SEARCH and SET statements or for comparisons with indexes or other index
data items. You cannot use index data items as subscripts or indexes.
RELATED TASKS
“Subscripting” on page 62
“Putting values into a table” on page 64
RELATED REFERENCES
INDEXED BY phrase (Enterprise COBOL Language Reference)
INDEX phrase (Enterprise COBOL Language Reference)
RELATED TASKS
“Loading a table dynamically”
“Loading a variable-length table” on page 69
“Initializing a table (INITIALIZE)”
“Assigning values when you define a table (VALUE)” on page 65
“Assigning values to a variable-length table” on page 70
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 item count. Then, if you make the table bigger, you need to change only
one value, instead of all references to a literal.
RELATED REFERENCES
PERFORM with VARYING phrase (Enterprise COBOL Language Reference)
The INITIALIZE statement cannot load a variable-length table (one that was defined
using OCCURS DEPENDING ON).
RELATED REFERENCES
INITIALIZE statement (Enterprise COBOL Language Reference)
64 Programming Guide
Assigning values when you define a table (VALUE)
If your table contains stable values (such as days and months), set the specific
values your table holds when you define it.
For example:
***********************************************************
*** 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.
(In this example, the items could all be initialized with one VALUE clause at the 01
level, because each item was being initialized to the same value.)
For example:
01 TABLE-ONE VALUE “1234”.
05 TABLE-TWO OCCURS 4 TIMES PIC X.
RELATED REFERENCES
REDEFINES clause (Enterprise COBOL Language Reference)
PERFORM statement (Enterprise COBOL Language Reference)
INITIALIZE statement (Enterprise COBOL Language Reference)
OCCURS clause (Enterprise COBOL Language Reference)
66 Programming Guide
Move Error-Message (Sub) To Print-Message
Perform 260-Print-Report
End-If
End-Perform
. . .
In this example, X is called the ODO subject, and Y is the ODO object.
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 PIC 9.
05 FIELD-2 OCCURS 1 TO 5 TIMES
DEPENDING ON FIELD-1 PIC X(05).
01 REC-2.
03 REC-2-DATA 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 (that is, if FIELD-1
contains an external 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, that
would be five occurrences of FIELD-2, plus FIELD-1, for a length of 26 bytes.
In this case, you need not set the ODO object (FIELD-1) before referencing REC-1 as
a receiving item. However, the sending field’s 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. 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 PIC 9.
05 FIELD-3 PIC 9.
68 Programming Guide
05 FIELD-2 OCCURS 1 TO 5 TIMES
DEPENDING ON FIELD-1 PIC X(05).
03 REC-2.
05 FIELD-4 OCCURS 1 TO 5 TIMES
DEPENDING ON FIELD-3 PIC X(05).
When you do a MOVE to REC-1 in this case, the actual length of REC-1 is calculated
immediately before the move using the current value of the ODO object (FIELD-1).
The compiler issues a message letting 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 (here LOCATION-TABLE-LENGTH) 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 587
RELATED TASKS
“Assigning values to a variable-length table” on page 70
“Loading a variable-length table”
Enterprise COBOL Compiler and Run-Time Migration Guide
RELATED REFERENCES
OCCURS DEPENDING ON clause (Enterprise COBOL Language Reference)
If the ODO object has a VALUE clause, it is logically initialized after the ODO subject
has been initialized. For example, in the following code
01 TABLE-THREE VALUE “3ABCDE”.
05 X PIC 9.
05 Y OCCURS 5 TIMES
DEPENDING ON X PIC X.
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 the first three elements, Y(1) through Y(3).
RELATED TASKS
Enterprise COBOL Compiler and Run-Time Migration Guide
RELATED REFERENCES
OCCURS DEPENDING ON clause (Enterprise COBOL Language Reference)
70 Programming Guide
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.
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 only of the order of
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 72
The conditions in the WHEN option 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 do not use AT END,
control passes to the next statement in your 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.
If the found condition comes after some intermediate point in the table, you can
speed up the search. Use 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 also
enables more efficient serial searching. If the table is large and is presorted, a
binary search is more efficient.
RELATED REFERENCES
SEARCH statement (Enterprise COBOL Language Reference)
To use the SEARCH ALL statement, your table must already be ordered on the key or
keys coded in the OCCURS clause. You can use any key in the WHEN condition, but
you must test all preceding data-names in the KEY option, if any. The test must be
an equal-to condition, and the KEY data-name must be either the subject of the
condition or the name of a conditional variable with which the tested
condition-name is associated. The WHEN condition can also be a compound
condition, formed from simple conditions with AND as the only logical connective.
The key and its object of comparison must be compatible.
RELATED REFERENCES
SEARCH statement (Enterprise COBOL Language Reference)
72 Programming Guide
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).
If an entry is found in which the three keys are equal to the given values (VALUE-1,
VALUE-2, and VALUE-3), PART-1 of that entry will be moved to OUTPUT-AREA. If
matching keys are not found in any of the entries in TABLE-A, the NOENTRY routine
is performed.
You might often need to process the data in tables iteratively. For intrinsic
functions that accept multiple arguments, you can use the ALL subscript to
reference all the items in the table or a single dimension of the table. The iteration
is handled automatically, making 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))
RELATED TASKS
“Using intrinsic functions (built-in functions)” on page 32
RELATED REFERENCES
Intrinsic functions (Enterprise COBOL Language Reference)
74 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:
v IF statement
v EVALUATE statement
v Switches and flags
v PERFORM statement
RELATED TASKS
“Selecting program actions”
“Repeating program actions” on page 82
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 79
RELATED REFERENCES
IF statement (Enterprise COBOL Language Reference)
EVALUATE statement (Enterprise COBOL Language Reference)
When one of the processing choices is no action, code the IF statement with or
without ELSE. Because the ELSE clause is optional, you can code the following:
IF condition-q
statement-1
END-IF
This coding is suitable for simple programming cases. For complex logic, you
probably need to use the ELSE clause. For example, suppose you have nested IF
statements with 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:
Use the EVALUATE statement to code a choice among three or more possible
conditions instead of just two. The EVALUATE statement is an expanded form of the
IF statement that allows you to avoid nesting IF statements for such coding, a
common source of logic errors and debugging problems.
With the EVALUATE statement, you can test any number of conditions in a single
statement and have separate actions for each. In structured programming terms,
this is a case structure. It can also be thought of as a decision table.
RELATED TASKS
“Coding conditional expressions” on page 79
“Using the EVALUATE statement” on page 77
“Using nested IF statements”
Use nested IF statements sparingly. The logic can be difficult to follow, although
explicit scope terminators and proper indentation help.
The following figure shows the logic structure for nested IF statements.
76 Programming Guide
RELATED TASKS
“Coding a choice of actions” on page 75
RELATED REFERENCES
Explicit scope terminators (Enterprise COBOL Language Reference)
You can code the EVALUATE statement to handle the case where multiple conditions
lead to the same processing by using the THRU phrase and by using multiple WHEN
statements.
When evaluated, each pair of selection subjects and selection objects must belong
to the same class (numeric, character, CONDITION TRUE or FALSE).
WHEN phrases are tested in the order they are coded. Therefore, you should order
these phrases for the best performance: code first the WHEN phrase containing
selection objects 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 75
Example: EVALUATE using multiple WHEN statements: You can use multiple
WHEN statements when several conditions lead to the same processing action. This
gives you more flexibility than using the THRU phrase, because the conditions do
not have to evaluate to values that fall in a range or evaluate to alphanumeric
values.
EVALUATE MARITAL-CODE
WHEN “M”
ADD 2 TO PEOPLE-COUNT
WHEN “S”
WHEN “D”
WHEN “W”
ADD 1 TO PEOPLE-COUNT
END-EVALUATE
78 Programming Guide
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”
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.
All conditional expressions that involve a national operand are national conditions.
The PROGRAM COLLATING SEQUENCE clause has no effect on national conditional
expressions.
RELATED CONCEPTS
“Switches and flags” on page 80
RELATED REFERENCES
Rules for condition-name values (Enterprise COBOL Language Reference)
Switch-status condition (Enterprise COBOL Language Reference)
Sign condition (Enterprise COBOL Language Reference)
Comparing numeric and alphanumeric operands (Enterprise COBOL Language
Reference)
Combined conditions (Enterprise COBOL Language Reference)
Class condition (Enterprise COBOL Language Reference)
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 81
To test for more than two values, as 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 have some association with logical values.
“Example: switches”
“Example: flags” on page 81
Example: switches
To test for an end-of-file condition for an input file named Transaction-File, you
could use the following data definitions:
WORKING-STORAGE Section.
01 Switches.
05 Transaction-EOF-Switch Pic X value space.
88 Transaction-EOF value “y”.
80 Programming Guide
The level-88 description says a condition named Transaction-EOF is turned on
when Transaction-EOF-Switch has value ’y’. Referencing Transaction-EOF in your
PROCEDURE DIVISION expresses the same condition as testing for
Transaction-EOF-Switch = “y”. For example, the following statement causes the
report to be printed only if your program has read to the end of the
Transaction-File and if the Transaction-EOF-Switch has been set to ’y’:
If Transaction-EOF Then
Perform Print-Report-Summary-Lines
Example: flags
Consider a program that updates a master file. The updates are read from a
transaction file. The transaction file’s records contain a field for the function 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 Pic X.
88 Add-Transaction Value “A”.
88 Change-Transaction Value “C”.
88 Delete-Transaction Value “D”.
The code in the PROCEDURE DIVISION for testing these condition-names might look
like this:
Evaluate True
When Add-Transaction
Perform Add-Master-Record-Paragraph
When Change-Transaction
Perform Update-Exisitng-Record-Paragraph
When Delete-Transaction
Perform Delete-Master-Record-Paragraph
End-Evaluate
When you use the SET condition-name TO TRUE statement, the switch or flag is set
back to the original value that was assigned in its data description.
For a level-88 item with multiple values, SET condition-name TO TRUE assigns the
first value (here, A):
88 Record-is-Active Value “A” “O” “S”
Using the SET statement and meaningful condition-names makes it easy for the
reader to follow your code.
The following example shows how to assign a value for 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
This code resets the switch to indicate that the end of the file has not been reached.
Use the PERFORM statement to loop (repeat the same code) a set number of times or
to loop based on the outcome of a decision.
RELATED TASKS
“Choosing inline or out-of-line PERFORM” on page 83
“Coding a loop” on page 84
“Coding a loop through a table” on page 85
“Executing multiple paragraphs or sections” on page 85
82 Programming Guide
RELATED REFERENCES
PERFORM statement (Enterprise COBOL Language Reference)
In the 1974 COBOL standard, the PERFORM statement is out-of-line and thus requires
an explicit branch to a separate paragraph and has an implicit return. If the
performed paragraph is in the subsequent sequential flow of your program, it is
also executed in that flow of the logic. To avoid this additional execution, you
must place the paragraph outside the normal sequential flow (for example, after
the GOBACK) or code a branch around it.
Coding a loop
Use the PERFORM . . . TIMES statement to execute a paragraph a certain number of
times:
PERFORM 010-PROCESS-ONE-MONTH 12 TIMES
INSPECT . . .
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 . . . WITH TEST AFTER . . . UNTIL if you want to execute the
paragraph at least once and then test before any subsequent execution. This
statement is equivalent to the 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 EQUAL DECEMBER)
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.)
84 Programming Guide
Coding a loop through a table
You can use PERFORM . . . VARYING 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 a loop through a table. You can use
either of the following forms:
PERFORM . . . WITH TEST AFTER . . . VARYING . . . UNTIL . . .
PERFORM . . . [WITH TEST BEFORE] . . . VARYING . . . UNTIL .
The following 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 . . .
In the code above, when control reaches the PERFORM statement, 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 it 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.
In terms of the application, this loop controls input-checking for the 12 fields of
item WS-DATA. Empty fields are not allowed, and this section of code loops through
and issues error messages as appropriate.
Intrinsic functions can make the coding of the iterative processing of tables simpler
and easier.
RELATED TASKS
“Processing table items using intrinsic functions” on page 73
RELATED TASKS
“Joining data items (STRING)”
“Splitting data items (UNSTRING)” on page 89
“Manipulating null-terminated strings” on page 91
“Referring to substrings of data items” on page 92
“Tallying and replacing data items (INSPECT)” on page 95
“Converting data items (intrinsic functions)” on page 96
“Evaluating data items (intrinsic functions)” on page 99
Chapter 7, “Coding for run-time use of national languages” on page 103
The STRING statement transfers data items into the receiving item in the order that
you indicate. In the STRING statement you can also specify the following:
v Delimiters that cause a sending field to be ended and another to be started
v Actions to be taken when the single receiving field is filled before all of the
sending characters have been processed (ON OVERFLOW condition)
You can specify a national item for any literal or identifier operand except the
POINTER identifier. However, if you specify a national item, you must specify all of
the literal and identifier operands (except the POINTER identifier) as national.
RELATED TASKS
“Handling errors in joining and splitting strings” on page 222
RELATED REFERENCES
STRING statement (Enterprise COBOL Language Reference)
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, the programmer initializes RPT-LINE to SPACES and sets
LINE-POS, the data item to be used as the POINTER field, to 4. (By coding the
POINTER phrase of the STRING statement, you can use the explicit pointer field to
control placement of data in the receiving field.) Then, the programmer codes this
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.
Item Positions
LINE-NO 4-8
Space 9
CUST-INFO 10 - 59
INV-NO 60 - 65
Space 66
DATE-DUE 67 - 74
Space 75
Portion of BAL-DUE that precedes the decimal point 76 - 81
88 Programming Guide
After the STRING statement is performed, the value of LINE-POS is 82, and RPT-LINE
appears as shown below.
You can specify national items as the sending field, receiving fields, and delimiters.
However, if you specify a national item, you must specify all of these operands as
national.
RELATED CONCEPTS
“Unicode and encoding of language characters” on page 105
RELATED TASKS
“Handling errors in joining and splitting strings” on page 222
Enterprise COBOL Compiler and Run-Time Migration Guide
RELATED REFERENCES
UNSTRING statement (Enterprise COBOL Language Reference)
Before issuing the UNSTRING statement, the programmer places the value 3 in
CHAR-CT (the POINTER field) to avoid working with the two control characters in
INV-RCD. A period (.) is placed in DBY-1 for use as a delimiter, and the value 0
(zero) is placed in FLDS-FILLED (the TALLYING field). The data is then read into
INV-RCD, as shown below.
90 Programming Guide
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,
/, is placed in DLTR-1, and the value 6 is placed in CTR-2.
4. Positions 31 through 33 are placed in INV-CLASS. The delimiter is a 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 examined and placed in M-UNITS. The
value 6 is placed in CTR-3. The delimiter is a 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 0 (zero). The delimiter is a
SPACE, but because no field has been 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 character 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 of data in
INV-RCD have not been examined, the ON OVERFLOW exit is taken, and execution
of the UNSTRING statement is completed.
After the UNSTRING statement is performed, the fields contain the values shown
below.
Field Value
DISPLAY-REC 707890 FOUR-PENNY-NAILS 000379
WORK-REC 475120000122BBA
CHAR-CT (the POINTER field) 55
FLDS-FILLED (the TALLYING field) 6
RELATED REFERENCES
Alphanumeric literals (Enterprise COBOL Language Reference)
As this example shows, you code two values separated by a colon, in parentheses,
immediately following the data item:
v Ordinal position (from the left) of the character that you want the substring to
start with
92 Programming Guide
v Length of the desired substring
The length is optional. If you omit the length, the substring extends to the end of
the item. Omit the length when possible as a simpler and less error-prone coding
technique.
You can code either of the two values as a variable or as an arithmetic expression.
You can also refer to substrings of table entries, including variable-length entries.
To refer to a substring of a table entry, you must code the subscript expression
before the reference modifier. For example, assuming 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 could code this statement:
MOVE ’D’ to PRODUCT-TABLE (2), (4:1)
Both numbers in the reference modifier must have a value of at least 1. Their sum
should not exceed the total length of the data item by more than 1 so that you do
not reference beyond the end of the desired substring.
The following options detect out-of-range reference modifiers, and flag violations
with a run-time message:
v SSRANGE compiler option
v CHECK run-time option
You can reference-modify national data items. The reference modifier position and
length for a national item are expressed in terms of national characters.
RELATED CONCEPTS
“Reference modifiers”
“Unicode and encoding of language characters” on page 105
RELATED TASKS
“Referring to an item in a table” on page 61
RELATED REFERENCES
“SSRANGE” on page 321
Reference modification (Enterprise COBOL Language Reference)
Function definitions (Enterprise COBOL Language Reference)
Reference modifiers
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:
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).
RELATED TASKS
“Referring to substrings of data items” on page 92
“Using national data (Unicode) in COBOL” on page 105
RELATED REFERENCES
Reference modification (Enterprise COBOL Language Reference)
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
94 Programming Guide
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.
RELATED REFERENCES
INTEGER-PART (Enterprise COBOL Language Reference)
INTEGER (Enterprise COBOL Language Reference)
RELATED CONCEPTS
“Unicode and encoding of language characters” on page 105
RELATED REFERENCES
INSPECT statement (Enterprise COBOL Language Reference)
In the following example, the INSPECT statement is used to examine and replace
characters in data item DATA-2. The number of times a leading 0 occurs in the data
item is accumulated in COUNTR. Every instance of the character A following the first
instance of the character C is replaced by the character 2.
77 COUNTR PIC 9 VALUE ZERO.
01 DATA-2 PIC X(11).
. . .
INSPECT DATA-2
TALLYING COUNTR FOR LEADING “0”
REPLACING FIRST “A” BY “2” AFTER INITIAL “C”
In the following example, the INSPECT statement is used to examine and replace
characters in data item DATA-3. Every character in the data item preceding the first
instance of a quote (“) 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
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 in the data item following the first instance of the character / but
preceding 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”?“
96 Programming Guide
You can use the NATIONAL-OF and DISPLAY-OF intrinsic functions to convert to and
from national (Unicode) strings.
RELATED CONCEPTS
“Unicode and encoding of language characters” on page 105
The code above displays the following messages on the system logical output
device:
Hello World!
HELLO WORLD!
hello world!
HELLO 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 be moved to the actual contents of Item-2.
For example, if the starting value is JOHNSONbbb, the value after the statement is
performed is bbbNOSNHOJ, where b represents a blank space.
When you reverse the order of a national string, the result is a national string.
Use NUMVAL-C when the argument includes a currency symbol or comma, or both,
as shown in the example. 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.
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
RELATED CONCEPTS
“Formats for numeric data” on page 40
RELATED TASKS
“Assigning input from a screen or file (ACCEPT)” on page 29
“Displaying values on a screen or in a file (DISPLAY)” on page 30
“Converting national data” on page 107
RELATED REFERENCES
NUMVAL (Enterprise COBOL Language Reference)
NUMVAL-C (Enterprise COBOL Language Reference)
“ARITH” on page 291
98 Programming Guide
Evaluating data items (intrinsic functions)
You can use several intrinsic functions in evaluating data items:
v CHAR and ORD for evaluating integers and single alphanumeric characters with
respect to the collating sequence used in your program
v MAX, MIN, ORD-MAX, and ORD-MIN for finding the largest and smallest items in a
series of data items, including national data items
v LENGTH for finding the length of data items, including national data items
v WHEN-COMPILED for finding the date and time the program was compiled
RELATED CONCEPTS
“Unicode and encoding of language characters” on page 105
RELATED TASKS
“Evaluating single characters for collating sequence”
“Finding the largest or smallest data item”
“Finding the length of data items” on page 101
“Finding the date of compilation” on page 101
If you know the ordinal position in the collating sequence of a character, and want
to know the character that it corresponds to, use the CHAR function with the integer
ordinal position as the argument. CHAR returns the desired character:
INITIALIZE Customer-Name REPLACING ALPHABETIC BY Function Char(65)
RELATED REFERENCES
CHAR (Enterprise COBOL Language Reference)
ORD (Enterprise COBOL Language Reference)
If you specify a national item for any argument, you must specify all arguments as
national.
If you used the ORD-MAX function in the example above, you would receive a syntax
error message at compile time; the reference to a numeric function is in an invalid
place. The following is a valid use of the ORD-MAX function:
Compute x = Function Ord-max(Arg1 Arg2 Arg3)
This code assigns the integer 3 to x if the same arguments are used as in the
previous example. If you use ORD-MIN instead, the integer 2 is returned. The above
examples would probably be more realistic if Arg1, Arg2, and Arg3 were instead
successive elements of an array (table).
If you specify a national item for any argument, you must specify all arguments as
national.
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 R1 Pic x(10) value “e”.
01 R2 Pic x(05) value “f”.
01 R3 Pic x(20) value spaces.
01 L Pic 99.
. . .
Move Function Max(R1 R2) to R3
Compute L = Function Length(Function Max(R1 R2))
If R1 contained ’g’ instead of ’e’, then R1 would evaluate as larger than R2, and:
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.
RELATED TASKS
“Performing arithmetic” on page 47
“Processing table items using intrinsic functions” on page 73
RELATED REFERENCES
ORD-MAX (Enterprise COBOL Language Reference)
ORD-MIN (Enterprise COBOL Language Reference)
The following COBOL statement demonstrates moving a data item into that field
in a record that holds customer names:
Move Customer-name To Customer-record(1:Function Length(Customer-name))
The LENGTH function returns the length of a national item in national characters.
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 allows 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.
RELATED TASKS
“Performing arithmetic” on page 47
“Processing table items using intrinsic functions” on page 73
RELATED REFERENCES
LENGTH (Enterprise COBOL Language Reference)
These characters show the four-digit year, month, day, and time (in hours, minutes,
seconds, and hundredths of seconds) of compilation.
The WHEN-COMPILED special register is another means you can use to find the date
and time of compilation. It has the following format:
The WHEN-COMPILED special register supports only a two-digit year, and carries the
time out only to seconds. This special register be used only as the sending field in
a MOVE statement.
RELATED REFERENCES
WHEN-COMPILED (Enterprise COBOL Language Reference)
Use these COBOL facilities to code and compile programs for run-time use of
national languages:
v National data type and national literals
v Two intrinsic functions:
– NATIONAL-OF to return a character string in UTF-16 representation
– DISPLAY-OF to convert a national string to a selected code page (EBCDIC,
ASCII, EUC, or UTF-8)
v Two compiler options:
– CODEPAGE to specify the code page to use for alphanumeric and double-byte
character set (DBCS) data in your program
– NSYMBOL to control whether national or DBCS processing is used for the N
symbol in literals and PICTURE clauses
Enterprise
COBOL
statement Can be national Comment For more information
ACCEPT identifier-1 Converted from EBCDIC “Assigning input from a screen or file
only if the CONSOLE option (ACCEPT)” on page 29
is specified directly or
indirectly
CALL identifier-2, identifier-3, “Passing data” on page 423
identifier-4, identifier-5;
literal-2, literal-3
COPY . . . operand-1, operand-2 “Compiler-directing statements” on
REPLACING page 332
DISPLAY identifier-1 Converted to EBCDIC only “Displaying values on a screen or in a
if the CONSOLE option is file (DISPLAY)” on page 30
specified directly or
indirectly
INITIALIZE REPLACING If you specify REPLACING “Examples: initializing variables” on
NATIONAL, identifier-2 and page 25
literal-1 must be of class
national, and vice versa.
INSPECT Identifiers and literals other If any of these is of class “Tallying and replacing data items
than identifier-3 (the national, all must be. (INSPECT)” on page 95
TALLYING identifier)
INVOKE method-name as identifier-2 “Invoking methods (INVOKE)” on
or literal-1; identifier-3 or page 480
literal-2 in the BY VALUE
phrase
RELATED CONCEPTS
“Unicode and encoding of language characters” on page 105
RELATED TASKS
“Using national data (Unicode) in COBOL” on page 105
“Converting national data” on page 107
“Processing UTF-8 data” on page 109
“Processing Chinese GB 18030 data” on page 110
“Comparing national data items” on page 110
RELATED REFERENCES
“CODEPAGE” on page 294
“NSYMBOL” on page 309
Each character set is a defined set of characters, but is not associated with a coded
representation. A coded character set (also referred to here as a code page) is a set of
unambiguous rules that relate the characters of the set to their coded
representation. Each code page is like a table that sets up the symbols for
representing a character set; each symbol is a unique bit pattern, or code point. Each
| code page has a unique coded character set identifier (CCSID), which is a value from
| 1 to 65,536.
UTF-8 represents ASCII invariant characters a-z, A-Z, 0-9, and certain special
characters such as ’ @ , . + - = / * ( ) identically as in ASCII. UTF-16 represents
such characters as X’00nn’ where X’nn’ is the representation of the character in
ASCII.
One or more encoding units are used to represent a character in a coded character
set. For UTF-16, an encoding unit takes 2 bytes of storage. Any character defined
in any EBCDIC code page is represented in one UTF-16 encoding unit when
converted to the national data representation.
RELATED TASKS
Chapter 7, “Coding for run-time use of national languages” on page 103
National literals
To specify national literals, use the prefix character N and compile with the option
NSYMBOL(NATIONAL). For example, you can use either of the following notations:
N“character-data”
N’character-data’
When you use 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 character NX. For
example:
NX“hexadecimal-digits”
Each of the following MOVE statements sets the data item X to the Unicode value
AB:
01 X pic NN usage national.
. . .
Move NX“00410042” to X
Move N“AB” to X
Move “AB” to X
Do not use alphanumeric hex literals in contexts that call for a national literal,
because such usage is easily misunderstood. For example, the statement:
Move X“C1C2C3C4” to X
When you use the figurative constant QUOTE, SPACE, or ZERO in a context that
requires national characters, the figurative constant represents a national character
value. However, you cannot use the figurative constants HIGH-VALUE and LOW-VALUE
in a context that requires national characters, such as a MOVE statement, an implicit
MOVE, or a relation condition with national operands.
1. Use the CODEPAGE compiler option to specify the code page for the EBCDIC code page
applicable to alphanumeric or DBCS data. National literals in your source program are
converted to UTF-16 for use at run time.
2. Most characters are represented in UTF-16 using one encoding unit. In particular, the
following cases are represented using a single UTF-16 encoding unit per character:
v COBOL characters A-Z, a-z, 0-9, space character, + -*/= $,;.“()><:’
v All characters that are converted from an EBCDIC code page
RELATED CONCEPTS
“Unicode and encoding of language characters” on page 105
RELATED TASKS
“Converting national data”
“Comparing national data items” on page 110
“Processing UTF-8 data” on page 109
RELATED REFERENCES
“CODEPAGE” on page 294
“NSYMBOL” on page 309
If the number of characters of the converted data is less than the size of the
national data item that you specify, the data is padded with default Unicode
UTF-16 space characters (NX’0020’). If the number of characters of the converted
data is more than the size of the national item, the trailing characters are truncated.
If you specify a code page as an argument to DISPLAY-OF and it differs from the
code page that you specify with the CODEPAGE compiler option, do not use the
DISPLAY-OF 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.
Conversion exceptions
Implicit or explicit conversion between national and alphanumeric data could fail
and generate a severity-3 Language Environment condition. Failures could occur if
any of the follow occur:
v Unicode Conversion Services was not installed on your system.
v The code page that you specified (implicitly or explicitly) is not a valid code
page.
v The combination of the CCSID that you specified explicitly or implicitly (such as
by using the CODEPAGE compiler option) and the UTF-16 Unicode CCSID (01200)
was not configured on your system as a valid conversion pair for the Unicode
Conversion Services on the system.
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 of
the target code page.
RELATED TASKS
Customizing Unicode support for COBOL (Enterprise COBOL Customization Guide)
RELATED REFERENCES
“CODEPAGE” on page 294
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
The following example illustrates these steps, converting Greek EBCDIC data to
UTF-8:
GB 18030 characters are encoded through the existing Chinese EBCDIC code page,
CCSID 1388, which has been expanded to include the GB 18030 characters that do
not require UTF-16 surrogate values. Surrogate values in UTF-16 are those characters
that require two 2-byte encoding units (4 bytes) for each character.
You can compare national data items explicitly or implicitly with certain
nonnational items in relation conditions in the following statements:
v EVALUATE
v IF
v PERFORM
v SEARCH
When you compare operands of unequal lengths, the shorter operand is treated as
if it were padded on the right with default Unicode UTF-16 space characters
(NX’0020’) to the length of the longer operand.
RELATED TASKS
“Using national data (Unicode) in COBOL” on page 105
“Coding a choice of actions” on page 75
“Tallying and replacing data items (INSPECT)” on page 95
“Coding a loop” on page 84
“Doing a serial search (SEARCH)” on page 71
“Joining data items (STRING)” on page 87
“Splitting data items (UNSTRING)” on page 89
RELATED REFERENCES
Relation condition (Enterprise COBOL Language Reference)
Comparison of numeric and alphanumeric operands (Enterprise COBOL Language
Reference)
The source of the information and the target for the results can be one or more of
the following:
v Another program
v Direct-access storage device
v Magnetic tape
v Printer
v Terminal
v Card reader or punch
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.
RELATED CONCEPTS
“File organization and input-output devices”
RELATED TASKS
“Choosing file organization and access mode” on page 115
“Allocating files” on page 117
“Checking for input or output errors” on page 118
With IBM Enterprise COBOL for z/OS and OS/390, 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. The
rate of data transfer is faster than it is for cards.
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)
RELATED TASKS
“Allocating files” on page 117
Chapter 9, “Processing QSAM files” on page 119
Chapter 10, “Processing VSAM files” on page 147
Chapter 11, “Processing line-sequential files” on page 173
“Choosing file organization and access mode”
The following table shows the possible file organizations, access modes, and record
formats for COBOL files.
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 116
“Allowable control characters” on page 174
RELATED TASKS
Chapter 9, “Processing QSAM files” on page 119
Chapter 10, “Processing VSAM files” on page 147
Chapter 11, “Processing line-sequential files” on page 173
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.
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
The COBOL run time deallocates all dynamic allocations at run unit termination,
except “implicit” CBLQDA allocations.
RELATED TASKS
“Setting and accessing environment variables” on page 398
“Defining and allocating QSAM files” on page 134
“Dynamically creating QSAM files with CBLQDA” on page 130
“Allocating VSAM files” on page 168
With VSAM files, you can use a second data-name in the FILE STATUS clause to get
additional VSAM return code information.
Another way of handling errors in input and output operations is to code ERROR
(synonymous with EXCEPTION) declaratives, as explained in the references below.
RELATED TASKS
“Handling errors in input and output operations” on page 223
“Coding ERROR declaratives” on page 227
“Using file status keys” on page 228
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.
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 141
Using access methods (z/OS DFSMS: Using Data Sets)
RELATED TASKS
“Defining QSAM files and records in COBOL”
“Coding input and output statements for QSAM files” on page 129
“Handling errors in QSAM files” on page 133
“Working with QSAM files” on page 133
“Processing QSAM ASCII files on tape” on page 143
“Processing ASCII file labels” on page 145
In the following example, COMMUTER-FILE-MST is your program’s name for the file;
COMMUTR is the external name.
Your ASSIGN clause name can include an S- before the external name (ddname or
environment variable name) to document that the file is a QSAM file.
RELATED TASKS
“Establishing record formats”
“Setting block sizes” on page 127
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 your FD entry for the file. If you want the records to
be blocked, code the BLOCK CONTAINS clause in your FD entry.
The following example shows how the FD entry might look for a file with
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 121
“Requesting variable-length format” on page 122
“Requesting spanned format” on page 124
“Requesting undefined format” on page 126
“Defining QSAM files and records in COBOL” on page 119
Logical records
The term logical record is used in a slightly different way in the COBOL language
and in z/OS QSAM. For format-V and format-S files, the 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.
RELATED REFERENCES
“Layout of format-F records”
“Layout of format-V records” on page 123
“Layout of format-S records” on page 125
“Layout of format-U records” on page 126
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 (RECORD clause format 1).
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 120
RELATED TASKS
“Requesting variable-length format” on page 122
“Requesting spanned format” on page 124
“Requesting undefined format” on page 126
“Establishing record formats” on page 120
RELATED REFERENCES
“Layout of format-F records”
RELATED TASKS
“Requesting fixed-length format” on page 121
Fixed-length record formats (z/OS DFSMS: Using Data Sets)
RELATED REFERENCES
“Layout of format-V records” on page 123
“Layout of format-S records” on page 125
“Layout of format-U records” on page 126
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 (RECORD clause format 3).
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.
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 (RECORD clause format 2).
Make integer-1 and integer-2 match the minimum length and the maximum
length 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
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 01-level 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 REFERENCES
“Layout of format-V records”
Moving from the VS COBOL II run time (Enterprise COBOL Compiler and Run-Time
Migration Guide)
Layout of format-V records: Format-V QSAM records have control fields (shown
below) preceding 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.
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, they’ll
be moved without the control bytes.
RELATED TASKS
“Requesting variable-length format” on page 122
RELATED REFERENCES
“Layout of format-F records” on page 121
“Layout of format-S records” on page 125
“Layout of format-U records” on page 126
You can omit the RECORDING MODE clause. The compiler determines the recording
mode to be S if the maximum record length 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 used for format V. The length is based on your
usage of the RECORD clause.
When creating files containing 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 long.
When retrieving files with format-S records, your 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.
v You have greater flexibility when you want to transfer logical records between
direct access storage types.
Format-S files and READ INTO: By specifying a READ INTO statement for a
format-S file, the record size just 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.
RELATED CONCEPTS
“Logical records” on page 120
“Spanned blocked and unblocked files” on page 125
RELATED REFERENCES
“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. The logical records can be either fixed or variable in length and their 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.
RELATED CONCEPTS
“Logical records” on page 120
RELATED TASKS
“Requesting spanned format” on page 124
Each block is preceded by a block descriptor field. 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 segment descriptor field. 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 124
RELATED REFERENCES
“Layout of format-F records” on page 121
“Layout of format-V records” on page 123
“Layout of format-U records” on page 126
| 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, and 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 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 (RECORD clause format 1), the record
length is the integer value, regardless of the lengths of the level-01 record
description entries associated with the file.
v If you use the RECORD IS VARYING clause (RECORD clause format 3), 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.
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 (RECORD clause
format 2), with integer-1 and integer-2 matching the minimum length and the
maximum length of the level-01 record description entries associated with the
file, the maximum record length is the integer-2 value.
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 size of the record just 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.
RELATED TASKS
“Requesting fixed-length format” on page 121
“Requesting variable-length format” on page 122
“Requesting spanned format” on page 124
“Establishing record formats” on page 120
RELATED REFERENCES
“Layout of format-U records”
RELATED TASKS
“Requesting undefined format” on page 126
RELATED REFERENCES
“Layout of format-F records” on page 121
“Layout of format-V records” on page 123
“Layout of format-S records” on page 125
If you set the block size explicitly in the BLOCK CONTAINS clause, it must not be
greater than the maximum block size for the device. The block size set for a
format-F file must be an integral multiple of the record length.
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
while doing one of the following:
v Reading a block of records of fewer than 12 bytes
v Writing a block of records of fewer than 18 bytes
Generally larger blocks 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.
If you specify a block size larger than 32760 directly on your BLOCK CONTAINS
clause or indirectly with the use of BLOCK CONTAINS n RECORDS, and you do not
meet both the following conditions, the OPEN of the data set fails with file status
code 90:
v You use OS/390 V2R10.0 DFSMS or later.
v You define the data set to be tape.
When you omit the BLKSIZE from the ddname definition, the block size is
automatically obtained by the system from the data set label.
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
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 an MVS system that uses OS/390 V2R10.0 DFSMS or
later and 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 run-time message is issued.
BLKSZLIM is device-independent.
RELATED TASKS
“Defining QSAM files and records in COBOL” on page 119
z/OS DFSMS: Using Data Sets
RELATED REFERENCE
BLOCK CONTAINS clause (Enterprise COBOL Language Reference)
RELATED TASKS
“Opening QSAM files” on page 130
“Adding records to QSAM files” on page 131
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)
Status key (Common processing facilities) (Enterprise COBOL Language Reference)
Code CLOSE WITH LOCK so that the file cannot be opened again while the program
is running.
Use the REVERSED option of the OPEN statement to process tape files in reverse order.
Execution of the OPEN statement will then position the file at its end. Subsequent
READ statements read the data records in reverse order, starting with the last record.
The REVERSED option is supported only for files with fixed-length records.
RELATED TASKS
“Dynamically creating QSAM files with CBLQDA”
RELATED REFERENCES
OPEN statement (Enterprise COBOL Language Reference)
Sometimes a QSAM file is unavailable on the operating system, but the COBOL
language defines that the file be created. The file is implicitly created for you if
you use the run-time option CBLQDA and one of the following circumstances exists:
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 and FD statements in your
program.
Do not confuse this implicit allocation mechanism with the dynamic allocation of
files through the use of environment variables. That explicit dynamic allocation
requires a valid environment variable to be set. This 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 130
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)
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 in the file. (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 the
| compressed format.
RELATED REFERENCES
REWRITE statement (Enterprise COBOL Language Reference)
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 clause,
COBOL first calculates the sum of LINAGE-COUNTER plus nn. Subsequent actions
depend on the size of nn. The END-OF-PAGE imperative statement 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 statement is performed.
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 option from
your WRITE statement, you get the equivalent of:
AFTER ADVANCING 1 LINE
RELATED REFERENCES
WRITE statement (Enterprise COBOL Language Reference)
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 you have set the TRAP(ON) run-time option,
the run time closes all open files that are defined in any COBOL programs in the
run unit.
v When Language Environment condition handling is 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 HLL language constructs
such as a C longjmp.
File status key data items that you define in the WORKING-STORAGE SECTION are set
when these implicit CLOSE operations are performed, but your EXCEPTION/ERROR
and LABEL declaratives are not invoked.
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)
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 run-time 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 223
RELATED REFERENCES
“Allocation of buffers for QSAM files” on page 140
You can optionally specify the following attributes in any order following the DSN:
v A disposition value, one of: NEW, OLD, SHR, or MOD
v TRACKS or CYL
v SPACE(nnn,mmm)
v VOL(volume-serial)
v UNIT(type)
v KEEP, DELETE, CATALOG, or UNCATALOG
v STORCLAS(storage-class)
v 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 this, define one of the following with a name that matches the external
name on your 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 specified parameters to do the following:
Some of the information about the QSAM file must always be coded in the
FILE-CONTROL entry, 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 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:
v Block size (BLKSIZE=), if BLOCK CONTAINS 0 RECORDS was coded at compile time
(which is 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.
RELATED TASKS
“Setting block sizes” on page 127
“Defining QSAM files and records in COBOL” on page 119
“Allocating files” on page 117
RELATED REFERENCES
“Parameters for creating QSAM files”
MVS JCL Reference
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”
To prevent common file status 39 problems, follow the guidelines listed below for
processing files that are existing, new, or dynamically created by COBOL.
If the existing file is an ASCII data set (DCB=(OPTCD=Q)), you must use the CODE-SET
clause in the program’s FD entry for the file.
When you do need to explicitly set a length attribute for the data set (for example,
you are using an ISPF allocation panel or if your DD statement is for a batch job in
which the program uses RECORD CONTAINS 0):
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 your 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 COBOL language used in your
program. In such a case, take the added byte into account when coding the
LRECL.
For example, suppose your program contains the following code for a file with
variable-length records:
RELATED TASKS
“Requesting fixed-length format” on page 121
“Requesting variable-length format” on page 122
“Requesting undefined format” on page 126
“Dynamically creating QSAM files with CBLQDA” on page 130
Striped extended-format QSAM data sets can benefit an application with these
characteristics:
v The application processes files that contain large volumes of data.
v The time for the input and output operations to the files significantly affects
overall performance.
For you to gain the maximum benefit from using QSAM striped data sets, 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 paragraph entry for the file.
Omitting the RESERVE clause allows DFSMS to 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) run-time option if the file is an EXTERNAL file with
format-F, format-V, or format-U records.
Notice 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 (performance considerations)
RELATED REFERENCES
“Allocation of buffers for QSAM files” on page 140
RELATED CONCEPTS
“Storage and its addressability” on page 33
RELATED TASKS
“Using striped extended-format QSAM data sets” on page 139
Usage notes
v File status 39 (fixed file attribute conflict) is not enforced for either of the
following:
– Record-length conflict
– Record-type conflict (fixed versus variable)
v A READ returns the number of bytes equal to that of the maximum logical record
size for the file except for the last record, which might be shorter.
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
the 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 117
“Defining and allocating QSAM files” on page 134
Accessing HFS files via BSAM and QSAM (z/OS DFSMS: Using Data Sets)
There are two kinds of labels: standard and nonstandard. IBM Enterprise COBOL
for z/OS and OS/390 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 143
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
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.
List the labels as data-names in the LABEL RECORDS clause in the FD entry for the file.
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 does
one of the following:
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.
RELATED CONCEPTS
“Labels for QSAM files” on page 141
Identifier Description
VOL1 Volume label
HDR1 or HDR2 Data set header labels
EOV1 or EOV2 Data set trailer labels (end-of-volume)
EOF1 or EOF2 Data set trailer labels (end-of-data-set)
UHL1 to UHL8 User header labels
UTL1 to UTL8 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.
The format used 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, or
v ASCII on 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), or
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 through eight labels are permitted.
Standard user labels are not supported for QSAM striped data sets.
RELATED CONCEPTS
“Labels for QSAM files” on page 141
In addition, if your program processes numeric data items from ASCII files, use the
separately signed numeric data type (SIGN IS LEADING SEPARATE).
If you are using 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.
BLKSIZE=n
n The size of the block, including the length of the block prefix.
LABEL=[AL|AUL|NL]
AL American National Standard (ANS) labels.
AUL ANS and user labels.
NL No labels.
OPTCD=Q
Q This value is required for ASCII files and is the default if the file is
created using Enterprise COBOL.
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.
Any labels on an ASCII tape must be in ASCII code only. Tapes containing a
combination of ASCII and EBCDIC cannot be read.
RELATED TASKS
“Processing QSAM ASCII files on tape” on page 143
The lists below show how VSAM terms differ from COBOL terms and other terms
that you might be familiar with.
The term file in this VSAM information 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 TASKS
“Defining VSAM file organization and records” on page 149
“Coding input and output statements for VSAM files” on page 155
“Protecting VSAM files with a password” on page 164
“Handling errors in VSAM files” on page 163
“Working with VSAM data sets under z/OS and UNIX” on page 165
“Improving VSAM performance” on page 171
RELATED REFERENCES
z/OS DFSMS: Using Data Sets
VSAM files
The physical organization of VSAM data sets differs considerably from those used
by other access methods. VSAM data sets are held in control intervals and control
areas (CA). The size of these is normally determined by the access method, and the
way in which they are used is not visible to you.
The following table compares the different types of VSAM data sets in terms of
several characteristics.
RELATED TASKS
“Specifying sequential organization for VSAM files” on page 150
“Specifying indexed organization for VSAM files” on page 150
“Specifying relative organization for VSAM files” on page 151
“Defining VSAM files” on page 165
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.
The following table summarizes VSAM file organization, access modes, and record
formats (fixed or variable length).
RELATED TASKS
“Specifying sequential organization for VSAM files”
“Specifying indexed organization for VSAM files”
“Specifying relative organization for VSAM files” on page 151
“Using file status keys” on page 228
“Using VSAM return codes (VSAM files only)” on page 229
“Defining VSAM files” on page 165
“Specifying access modes for VSAM files” on page 153
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 148
Here data-name is the name of the key field as you defined it in the record
description entry in the DATA DIVISION. The collation of index record keys is based
on the binary value of the key, regardless of the class or the category of the key.
The following example shows the statements for a VSAM indexed file (KSDS) that
is accessed dynamically. In addition to the primary key, COMMUTER-NO, there is an
alternate key, LOCATION-NO:
Alternate keys
In addition to the primary key, you can also code one or more alternate keys to use
for retrieving records. Using alternate keys, you can access the indexed file to read
records in some sequence other than the prime key sequence. For example, you
could access the file through employee department rather than through employee
number. Alternate keys need not be unique. More than one record will be accessed,
given a department number as a key. This is permitted if alternate keys are coded
to allow duplicates.
You define the alternate key in your COBOL program with the ALTERNATE RECORD
KEY clause:
ALTERNATE RECORD KEY IS data-name
Here data-name is the name of the key field as you defined it in the record
description entry in the DATA DIVISION. The collation of alternate keys is based on
the binary value of the key, regardless of the class or the category of the key.
Alternate index
To use an alternate index, you need to define a data set (using access method
services) called the alternate index (AIX). 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.
RELATED CONCEPTS
“VSAM files” on page 148
RELATED TASKS
“Creating alternate indexes” on page 166
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 ITEM-NO:
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
randomizing algorithm is the division/remainder technique. With this technique,
When you load an RRDS with variable-length records, you can skip over relative
record numbers. Unlike fixed-length RRDS, a variable-length RRDS does not have
slots. Instead, the free space that you define allows for more efficient record
insertions.
The coding that you use in your COBOL program to identify and describe VSAM
variable-length RRDS and COBOL simulated variable-length RRDS is similar. How
you use the SIMVRD run-time option and whether you define the VSAM file as a
RRDS or KSDS differs, however.
When you define the cluster in step 4 for simulated variable-length RRDS, observe
these restrictions:
v Do not define an alternate index.
v Do not specify a KEYRANGE.
v Do not specify SPANNED.
Also, use the REUSE parameter when you open for output a file that contains
records.
Errors: When you work with simulated variable-length relative data sets and true
VSAM RRDS data sets, you get an OPEN file status 39 if your COBOL file definition
and the VSAM data set attributes do not match.
RELATED CONCEPTS
“VSAM files” on page 148
RELATED TASKS
“Defining VSAM files” on page 165
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.
RELATED TASKS
“Reading records from a VSAM file” on page 159
RELATED TASKS
“Reading records from a VSAM file” on page 159
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.
Clause
RECORD clause format Record length Comments
Code RECORD CONTAINS 1 Fixed in size with a The lengths of the
integer. length of integer-2 level-01 record
description entries
associated with the file
do not matter.
Omit the RECORD clause, The fixed size that you
but code all level-01 coded
records (associated with
the file) as the same size
and none with an OCCURS
DEPENDING ON clause.
Clause
RECORD clause format Maximum record length Comments
Code RECORD IS VARYING 3 integer-2 value The lengths of the
FROM integer-1 TO integer-2. level-01 record
description entries
associated with the file
do not matter.
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 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 TASKS
Enterprise COBOL Compiler and Run-Time Migration Guide
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 with sequential files (ESDS).
The X indicates that you can use the statement with the open mode at the top of
the column.
The following table shows the possible combinations you can use with indexed
(KSDS) files and relative (RRDS) files. The X indicates that you can use the
statement with the open mode at the top of the column.
The fields 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.
RELATED CONCEPTS
“File position indicator” on page 157
RELATED REFERENCES
Status key (Common processing facilities) (Enterprise COBOL Language Reference)
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 159
For example, if you OPEN EXTEND, OPEN I-O, or OPEN INPUT a file that is neither
optional nor available, you get file status 35 and the OPEN statement fails. If the file
is OPTIONAL, the OPEN EXTEND, OPEN I-O, or OPEN INPUT 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 that file
in the SELECT and FD statements of your COBOL program. Mismatches in the
following items result in a file status code 39, and the OPEN statement fails:
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 in your COBOL program 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.
RELATED REFERENCES
“Statements to load records into a VSAM file” on page 159
Optional files are files that are not necessarily present each time the program is
run. You can define files opened in INPUT, I-O, or OUTPUT mode as optional by
defining them with the SELECT OPTIONAL phrase in the FILE-CONTROL section of
your program.
Initially loading records sequentially into a file: Initially loading a file means
writing records into the file for the first time. This is not the same as writing
records into a file from which all previous records have been deleted.
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 impact 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.
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.
RELATED TASKS
“Opening a loaded file (a file with records)”
RELATED REFERENCES
“Statements to load records into a VSAM file”
REPRO (z/OS DFSMS: Access Method Services for Catalogs)
RELATED TASKS
“Opening an empty file” on page 158
“Updating records in a VSAM file” on page 160
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.
RELATED TASKS
“Opening an empty file” on page 158
“Working with VSAM data sets under z/OS and UNIX” on page 165
RELATED REFERENCES
“Statements to load records into a VSAM file”
z/OS DFSMS: Access Method Services for Catalogs
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 157
RELATED TASKS
“Specifying access modes for VSAM files” on page 153
RELATED REFERENCES
“Statements to load records into a VSAM file” on page 159
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.
To replace records randomly or dynamically, your program need not read the
record to be rewritten. Instead, to position the record that you want to update, do
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.
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 need not
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.
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) run-time option has been
set, all open files defined in any COBOL programs in the run unit are closed.
File status key data items that you define in the WORKING-STORAGE SECTION are set
when these implicit CLOSE operations are performed, but your EXCEPTION/ERROR
and LABEL declaratives are not invoked.
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.
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 when you have 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 input/output error occurs.
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 return 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 every input or output request, especially
OPEN and CLOSE.
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 run-time option
ABTERMENC(ABEND).
RELATED REFERENCES
VSAM macro return and reason codes (z/OS DFSMS Macro Instructions for Data
Sets)
To use explicit passwords, code the PASSWORD clause in the SELECT statement of
your program. 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.
A VSAM file is unavailable if it has never contained a record, even if you have
defined it.
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 166
“Allocating VSAM files” on page 168
“Sharing VSAM files through RLS” on page 170
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 access method services DEFINE CLUSTER command to define your VSAM
data sets (clusters). This process includes creating an entry in an integrated catalog
without any data transfer.
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 will be 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 will use the length specified in the 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.
v For COBOL simulated variable-length relative-record data sets, specify the
average size of the COBOL records and a size that is greater than or equal to the
maximum size COBOL record plus 4:
DEFINE CLUSTER INDEXED
KEYS(4,0)
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 168
“Specifying relative organization for VSAM files” on page 151
RELATED REFERENCES
z/OS DFSMS: Access Method Services for Catalogs
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
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.
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. This command BLDINDEX reads all the records in
your VSAM indexed data set (or base cluster) and extracts the data needed to
build the alternate index.
Alternatively, you can use the run-time option AIXBLD to build the alternate
index at run time. However, this option might adversely affect run-time
performance.
RELATED REFERENCES
AIXBLD (COBOL only) (Language Environment Programming Reference)
Using JCL:
//MASTERA DD DSNAME=clustername,DISP=OLD (1)
//MASTERA1 DD DSNAME=path1,DISP=OLD (2)
//MASTERA2 DD DSNAME=path2,DISP=OLD (3)
RELATED TASKS
“Creating alternate indexes” on page 166
Allocation of VSAM files (indexed, relative, and sequential) follows the general
rules for the allocation of COBOL files. If you use an environment variable to
allocate a VSAM file, you must specify these options in the order shown, but no
others:
v DSN(dsname), where dsname is the name of the base cluster
v OLD or SHR
The basic DD statement that you need for your VSAM files is:
//ddname DD DSN=dsname,DISP=SHR,AMP=AMORG
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 used to supplement 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 not required except under the following circumstances:
v You use a dummy VSAM data set. For example,
//ddname DD DUMMY,AMP=AMORG
v You request additional index or data buffers. For example,
//ddname DD DSN=VSAM.dsname,DISP=SHR,
// AMP=(’BUFNI=4,BUFND=8’)
You cannot specify AMP if you allocate your 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 of the SELECT statement in
your COBOL program.
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 one 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 SELECT statement).
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 and 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 117
You cannot specify RLS if you allocate your VSAM data set with an environment
variable.
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 and another user might update the record.
The locking rules for RLS=CR can cause the application to wait for availability of a
record lock, and this wait might slow down the READ for input.
You might need to modify your application logic to use the RLS=CR capability. Do
not use the RLS JCL 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 a
good idea to issue an OPEN or START immediately before a READ. If there is a delay
between the OPEN or START and the actual 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.
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
“Specifying access modes for VSAM files” on page 153
Deciding how big a virtual resource pool to provide (z/OS DFSMS: Using Data Sets)
Selecting the optimal percentage of free space (z/OS DFSMS: Using Data Sets)
RELATED REFERENCES
z/OS DFSMS: Access Method Services for Catalogs
After you have created a record, you cannot change its length or its position in the
file, and you cannot delete it.
RELATED CONCEPTS
UNIX System Services User’s Guide
RELATED TASKS
“Defining line-sequential files and records in COBOL”
“Describing the structure of a line-sequential file” on page 174
“Coding input-output statements for line-sequential files” on page 175
“Handling errors in line-sequential files” on page 178
“Defining and allocating line-sequential files” on page 175
RELATED REFERENCES
“Allowable control characters” on page 174
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.
Your ASSIGN assignment-name clause must not include an organization field (S- or
AS-) before the external name. The ACCESS phrase and the FILE STATUS phrase are
optional.
RELATED REFERENCES
“Allowable control characters”
The new-line 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 173
Code the logical size of the records with 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:
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 173
“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)
To define a line-sequential file, define one of the following with a name that
matches the external name on your ASSIGN clause:
v A DD allocation:
– A DD statement that specifies PATH=’absolute-path-name’
– A TSO allocation that specifies PATH(’absolute-path-name’)
RELATED TASKS
“Allocating files” on page 117
“Defining line-sequential files and records in COBOL” on page 173
RELATED REFERENCES
MVS JCL Reference
RELATED TASKS
“Defining line-sequential files and records in COBOL” on page 173
“Describing the structure of a line-sequential file” on page 174
“Opening line-sequential files”
“Reading records from line-sequential files”
“Adding records to line-sequential files” on page 177
“Closing line-sequential files” on page 177
“Handling errors in line-sequential files” on page 178
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)
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 177
“Closing line-sequential files” on page 177
“Defining and allocating line-sequential files” on page 175
RELATED REFERENCES
OPEN statement (Enterprise COBOL Language Reference)
CLOSE statement (Enterprise COBOL Language Reference)
With sequential processing, your program reads one record after another in the
same order in which the records were entered when the file was created.
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 new-line 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.)
RELATED TASKS
“Opening line-sequential files” on page 176
“Adding records to line-sequential files”
“Closing line-sequential files”
“Defining and allocating line-sequential files” on page 175
RELATED REFERENCES
OPEN statement (Enterprise COBOL Language Reference)
WRITE statement (Enterprise COBOL Language Reference)
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. External decimal data items must be unsigned or declared with
the SEPARATE CHARACTER phrase if signed.
RELATED TASKS
“Opening line-sequential files” on page 176
“Reading records from line-sequential files” on page 176
“Closing line-sequential files”
“Defining and allocating line-sequential files” on page 175
RELATED REFERENCES
OPEN statement (Enterprise COBOL Language Reference)
WRITE statement (Enterprise COBOL Language Reference)
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) run-time 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.
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 176
“Reading records from line-sequential files” on page 176
“Adding records to line-sequential files” on page 177
“Defining and allocating line-sequential files” on page 175
RELATED REFERENCES
CLOSE statement (Enterprise COBOL Language Reference)
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, it is possible that your
program could continue; but the results will probably not be what you expected.
RELATED TASKS
“Coding input-output statements for line-sequential files” on page 175
“Handling errors in input and output operations” on page 223
You can mix SORT and MERGE statements in the same COBOL program. 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.
Restrictions:
v You cannot run a COBOL program that contains SORT or MERGE statements under
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 180
RELATED TASKS
“Describing the sort or merge file” on page 180
“Describing the input to sorting or merging” on page 181
“Describing the output from sorting or merging” on page 183
“Requesting the sort or merge” on page 186
“Determining whether the sort or merge was successful” on page 190
RELATED REFERENCES
“CICS SORT application restrictions” on page 197
SORT statement (Enterprise COBOL Language Reference)
MERGE statement (Enterprise COBOL Language Reference)
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. 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. You
can order the records in either ascending or descending order of each key.
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 REFERENCES
SORT statement (Enterprise COBOL Language Reference)
MERGE statement (Enterprise COBOL Language Reference)
Sort-Work-1 is the name of the file in your program. Use this name to refer to
the file.
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. You do
not need to provide a ddname definition for the file.
RELATED REFERENCES
“FILE SECTION entries” on page 13
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 182
“Requesting the sort or merge” on page 186
RELATED REFERENCES
“FILE SECTION entries” on page 13
RELATED TASKS
“Requesting the sort or merge” on page 186
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.
The following table compares the RELEASE and RELEASE FROM statements.
RELATED REFERENCES
“Restrictions on input and output procedures” on page 185
RELEASE statement (Enterprise COBOL Language Reference)
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”
“Requesting the sort or merge” on page 186
RELATED REFERENCES
“FILE SECTION entries” on page 13
You can use the AT END and END-RETURN phrases with the RETURN statement. The
imperative statements on 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 the RETURN INTO statement instead of RETURN, your records will be
returned to WORKING-STORAGE or to an output area.
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.
RELATED REFERENCES
“Restrictions on input and output procedures” on page 185
RETURN statement (Enterprise COBOL Language Reference)