Advanced Cobol
Advanced Cobol
Documentation
IBM Enterprise COBOL for z/OS
http://www-306.ibm.com/software/awdtools/cobol/zos/library/
Course Outline
QSAM File Processing
- Defining files - Dynamic File processing in COBOL
Subprograms
CALL Parameter passing techniques CANCEL Nested programs Recursion Single Dimension Multi-Dimension Subscripts and Indexes Searching
Tables
Course Outline
Debugging
Basics Dumps
Course Outline
Files with Variable Length Records Strings
STRING UNSTRING INSPECT Reference modification
Course Outline
Files with Variable Length Records Strings
STRING UNSTRING INSPECT Reference modification
QSAM Files
Unkeyed, Sequentially created and processed Records cannot change length or position QSAM files on direct access storage can be modified with REWRITE ENVIRONMENT DIVISION. FILE-CONTROL paragraph SELECT I-O-CONTOL paragraph APPLY WRITE-ONLY DATA DIVISION FILE SECTION FD
Environment Variables
Environment Variables
Defined as WORKING-STORAGE fields using value clauses
01 FILE-ENV-VAR PIC X(39) VALUE DYNFILE=DSN(INPUT.FILE) SHR.
RESERVE Clause
Specifies the number of I/O buffers allocated the file at run-time If omitted, the number of buffers is taken from the DD statement. If none are specified, the system default is taken
QSAM Buffering
QSAM buffers can be allocated above the 16 MB line if all of the following are true: - Enterprise COBOL - z/OS Language Environment - the programs are compiled with RENT and DATA(31) or compiled with NORENT and | RMODE(ANY) - the program is executing in AMODE 31 - the program is executing on MVS - the ALL31(ON) run-time option is used (for EXTERNAL files)
PADDING Clause
PADDING data name CHARACTER IS literal
Specifies a character for block padding on sequential files Data name a one character field Literal a one character alphanumeric literal or national symbol
SEQUENTIAL IS
- The operating system moves a value to dname1 and possibly dname2 after each I/O operation. -dname1 - a two character alphanumeric or national field -dname2 used for VSAM
EXTERNAL
The EXTERNAL clause specifies that a file connector is external, permitting file sharing between two programs in the same run unit
GLOBAL
GLOBAL clause specifies the fileconnector name is available to the declaring program and all programs contained directly or indirectly Used for nested programs
BLOCK CONTAINS
BLOCK CONTAINS 0 RECORDS If this clause is omitted, records are unblocked by default! Allows the blocksize to be specified in the JCL or by the operating system Code this Statement! (TSYS Standard)
RECORD Clause
Specifies the number of bytes in a record (fixed or variable) When omitted, the compiler determines lengths based on record descriptions. RECORD CONTAINS 80 CHARACTERS RECORD CONTAINS 50 TO 80 CHARACTERS RECORD IS VARYING IN SIZE FROM 40 TO 60 CHARACTERS DEPENDING ON REC-COUNT.
RECORDING MODE
Specifies the format of physical records in a QSAM file (ignored for VSAM) F fixed size, V variable size, U unblocked, fixed or variable, S spanned, large records that span a block
RECORDING RECORDING RECORDING RECORDING MODE MODE MODE MODE IS IS IS IS F V U S
FD Example
FD IN-FILE IS GLOBAL RECORDING MODE F BLOCK CONTAINS 0 RECORDS LABEL RECORDS ARE STANDARD RECORD CONTAINS 80 CHARACTERS DATA RECORD IS IN-AREA. 01 IN-AREA. 05
LABEL RECORDS
Label records are records written at the beginning and end of DASD and Tape files that provide information about file Enterprise COBOL only supports standard labels LABEL RECORDS ARE STANDARD LABEL RECORDS ARE OMITTED
Subprograms
Calling a Subprogram
Syntax for CALL
CALL subprog name [ USING [BY REFERENCE | BY CONTENT] ident1 ] END-CALL
The subprog name usually refers to an 8 byte field that contains the program name to be called Static call is made when subprogram name is hard-coded and compiler option = NODYNAM Subprogram can be written in any supported language
Calling a Subprogram
CALL variable-name [ USING [BY REFERENCE | BY CONTENT | BY CONTENT LENGTH OF | BY CONTENT ADDRESS OF ] ident1 ] END-CALL
The variable-name usually refers to an 8 byte field that contains the program name to be called Names can be longer with Enterprise COBOL The variable-name can be modified as the program is running to call different programs
Calling a Subprogram
Linking to the called program is dynamic At TSYS, all calls are dynamic ( DYNAM compiler option) BY REFERENCE is the default BY REFERENCE provides the subprogram with access to a main program variable. The receiving variable is an alias for the passed variable BY CONTENT provides the subprogram with access to a copy of a main program variable
Calling a Subprogram
BY CONTENT ADDRESS OF provides a copy of the address of the passed variable (must be a linkage area name) BY CONTENT LENGTH provides a copy of the length of a variable
Example Parameters
Or
ENTRY COMPUTE USING COST RESULT.
Or
PROCEDURE DIVISION USING A COST RESULT.
The variables in the using statement are 01 group items defined in the LINKAGE SECTION or 77 items LINKAGE SECTION. 01 A PIC X(8). O1 COST PIC S9(5) PACKED-DECIMAL. 01 RESULT PIC S9(5) BINARY.
Exercise #1
Create a main program that calls a subprogram Print I am in the main program in the main program Call the subprogram Print I am in the subprogram in the subprogram Print I am back in the main program in the main.
Exercise #2
Create a two variables X and Y in the main program (you pick the type and value). Print the values of X and Y in the main program Pass X BY REFERENCE and Y BY CONTENT to the subprogram Print the variables in the subprogram Change the values of each variable in the subprogram Print the length of x by passing the length using BY CONTENT LENGTH (Receiving variable PIC S9(8) BINARY) Print the values of the variables again in the main program
Canceling a Subprogram
CANCEL syntax
CANCEL CANCEL literal identifier
Canceling a program means the program will be in its initial state if the program is called again Canceling a program closes all files associated with an internal file connector of the canceled program No action is taken when canceling a previously canceled program or one that has not been dynamically called
Exercise #3
Have the main program call a subprogram four times. Create a local numeric variable Z in the subprogram with initial value 1. Each time the program is called, print Z and then add 1 to it. Repeat the experiment after adding IS INITIAL to the PROGRAM-ID
PROGRAM-ID. MYPROG IS INITIAL.
Subprograms
Subprograms remain in their last used state when they terminate with EXIT PROGRAM or GOBACK A program that is coded with INITIAL will always be called with its initial state
Exercise #4
Repeat Exercise #3, canceling each program after each subprogram call
Return Codes
Use the RETURN-CODE special register to test and transmit return codes through register 15 After calling a subprogram, test RETURNCODE to see if the subprogram completed normally At the end of a suprogram, set RETURNCODE to indicate the results of the call
Exercise #5
Write a main program that passes a numeric parameter, say X, to a subprogram. If the parameter is negative have the subprogram set a return code of 4. If the parameter is nonnegative, the subprogram should set the return code to 0. Have the main program test the return code after the subprogram has completed. The main program should print a message indicating the type of number the subprogram received. Try running the main program passing negative and non-negative values for X.
External Files
Files can be shared by multiple programs in the same run unit. Each program declares the file to be EXTERNAL FD MYFILE IS EXTERNAL RECORD CONTAINS 80 CHARACTERS RECORDING MODE IS F. 01 MY-RECORD.
External Files
Each program has the same SELECT statement: SELECT MY-FILE ASSIGN TO MYFILE FILE STATUS IS MYSTATUS ORGANIZATION IS SEQUENTIAL.
External Files
Make the file status field external so there is only one shared field for all programs. Each program declares: 01 MYSTATUS PIC 99 EXTERNAL. Be sure to work in locate-mode.
Exercise #6
Write a main program that opens a sequential file and calls a subprogram each time it needs a record. Write a subprogram that reads a single record and returns to the main program. Have the main program print all the records in the sequential file and then close the file. Share the same file between the two programs by making the file external with a shared file status field.
Nested Programs
Avoided in production programs at TSYS Convenient for developing (one file, one compilation) Nested programs can be separated easily into regular programs after debugging Can be used instead of PERFORM CALL to a nested program is as efficient as a PERFORM Each program ends with END PROGRAM
PROGRAM X
Exercise #7
Convert one of your main programs and subprograms to a nested program version Canceling only makes sense for dynamically called programs Cause an abend in your subprogram. Look at the storage dump and error information. Is it any harder to debug than a regular program?
The COBOL program will receive the parm through the LINKAGE SECTION Code a LINKAGE SECTION description similar to this:
01 PARM-BUFF. 05 PARM-LEN 05 PARM-DATA PIC S9(4) BINARY. PIC X(256).
Exercise #8
Try coding a main program that receives a parm and prints it out Run the program with the following EXEC statements:
// EXEC PGM=PROGNAME,PARM=HI! // EXEC PGM=PROGNAME,PARM=HI THERE! // EXEC PGM=PROGNAME,PARM=ABCDEFGHIJKLMNOPQRSTUV'
Omitted Parameters
You can leave out some arguments when coding a CALL statement by coding OMITTED in place of the passed variable
CALL THATPROG USING P1,OMITTED,P3
Test for the OMITTED parameter by checking to see if the address of the received parm is NULL.
PROCEDURE DIVISION USING X Y Z. IF ADDRESS OF Y = NULL DISPLAY PARM Y WAS NOT PASSED END-IF
Tables
Employee Table
EMPLOYEE-REC(1)
Joe Brown Joe Betty Brown Smith Joy Dokes Jim Doyle
10 10 30 31 32
20 20 40 45 90
LOC-CODE(3)
NAME(3) EMP-NO(4)
Exercise #9
Implement a single dimension table of days. Print the table from beginning to end Turn the table into a fat table by adding a column with the number of letters in each day name. Print each day name and the number of letters it contains.
Multi-Dimension Tables
COBOL supports up to 7 dimensions in tables Use OCCURS within OCCURS to add multiple dimensions
01 EMP-TABLE 05 EMPLOYEE 10 NAME 10 HOURS OCCURS 100 TIMES. PIC X(30). PIC S99 OCCURS 7 TIMES.
Multi-Dimension Table
01 EMP-TABLE. 05 EMPLOYEE OCCURS 3 TIMES. 10 NAME PIC X(30). 10 HRS PIC S99 OCCURS 3 TIMES.
NAME(1) NAME(2) NAME(3) HRS(1,1) HRS(2,1) HRS(3,1) HRS(1,2) HRS(1,3)
EMPLOYEE(3)
Exercise #10
Create a table of integers with 4 rows and 5 columns. Print the table row by row Print the table column by column Compute and print the sum of each row Compute and print the sum of each column Compute and print the sum of all entries in the table
Subscripts vs Indexes
Subscripts
Represent an occurrence number User defined as a numeric field best to choose USAGE IS BINARY Printable (since they are numeric) Can use relative subscripts J+1 or J-3 Manipulated with PERFORM loops, assignments, and arithmetic commands
Subscripts vs Indexes
Indexes
Represent a displacement value from the start of a table. More efficient than subscripts Created automatically when a table is defined with indexes Cant be printed Manipulated with PERFORM loops, and SET statements
SET Statements
Examples
SET J TO K SET J TO 1 SET K UP BY 1 SET K DOWN BY 1 SET K TO K + 1
Exercise #11
Convert Exercise #10 so that you are using indexes instead of subscripts
Sequential Search
COBOL provides a SEARCH command that provides a sequential search for tables that have indexes Table entries do not have to be sorted AT END clause provides code in the situation that the search is unsuccessful Searching starts with the current index value
SEARCH
Sequential Searching
01 EMPLOYEE-TABLE. 05 EMPLOYEE OCCURS 100 TIMES INDEXED BY I-NDX. 10 EMP-NO PIC 9(5). 10 EMP-RANK PIC X(5). SET I-NDX TO 1 SEARCH EMPLOYEE AT END DISPLAY NOT FOUND WHEN EMP-NO(I-NDX) = 12345 DISPLAY EMP-RANK(I-NDX) END-SEARCH
Sequential Searching
01 EMPLOYEE-TABLE. 05 EMPLOYEE OCCURS 100 TIMES INDEXED BY I-NDX. 10 EMP-NO PIC 9(5). 10 EMP-RANK PIC X(5). SET I-NDX TO 1 SEARCH EMPLOYEE AT END DISPLAY NOT FOUND WHEN EMP-NO(I-NDX) < 10000 DISPLAY EMP-RANK(I-NDX) WHEN EMP-NO(I-NDX) > 2000 DISPLAY EMP-RANK(I-NDX) END-SEARCH
Exercise #12
Create a fat single dimension table with the data in the file DATA1. Read the file and store the second (Item #) and third fields (Item name) in the table. Assume a fixed size table of 40 items. Sequentially search the table for item # 400 and 450. Print out the results of the search.
Binary Searching
Entire table is searched. No need to initialize an index Table must have an ASCENDING or DESCENDING KEY IS clause. Table must be sorted. Only one When clause and WHEN clause is one or more equal tests joined by AND operators AT END clause is invoked if the WHEN clause is never satisfied
Binary Search
Binary Searching
01 EMPLOYEE-TABLE. 05 EMPLOYEE OCCURS 100 TIMES ASCENDING KEY IS EMP-NO INDEXED BY I-NDX. 10 EMP-NO PIC 9(5). 10 EMP-RANK PIC X(5). SEARCH ALL EMPLOYEE AT END DISPLAY NOT FOUND WHEN EMP-NO(I-NDX) = 12345 DISPLAY EMP-RANK(I-NDX) END-SEARCH
SEARCH ALL
SEARCH ALL performs a binary search with an index ENTRIES MUST BE IN ORDER No SET necessary (whole table searched) 01 SALES-TAX. 05 TAB-ENTRIES OCCURS 100 TIMES ASCENDING KEY ZIPCODE INDEXED BY K. 10 ZIPCODE PIC 9(5). 10 RATE PIC V999. SEARCH ALL TAB-ENTRIES AT END MOVE 0 TO TAX WHEN ZIPCODE(K) = ZIPIN COMPUTE TAX = RATE(K) * AMOUNT END-SEARCH
Exercise #13
Convert Exercise #12 to a binary search.
10 NAME 10 AGE
Exercise #14
Convert Exercise #12 to a variable length table. Assume you dont know how many items will be in the table, but the range is 30 to 100 items.
Intrinsic Functions
MEAN ( ARG1, ARG2,) MEDIAN (ARG1, ARG2) STANDARD-DEVIATION(ARG1,ARG2,) VARIANCE (ARG1,ARG2, ) RANGE (ARG1, ARG2, ) MAX (ARG1, ARG2, ) MIN (ARG1, ARG2, ) ORD-MIN (ARG1,ARG2,) ORD-MAX (ARG1,ARG2,) SUM (ARG1, ARG2, )
Intrinsic Functions
CURRENT-DATE UPPER-CASE (ARG) LOWER-CASE(ARG) ANNUITY(RATE,NO-OF-PAYMENTS)- returns a decimal fraction that when multiplied by loan amount produces the payment. Rate must be consistent with payment period. PRESENT-VALUE(RATE,AMT1,AMT2,) returns the present value of future payments
Intrinsic Functions
SQRT(ARG) REM(ARG1,ARG2) returns the remainder of arg1 divided by arg2 MOD(ARG1,ARG2)- similar to REM but with integer arguments INTEGER(ARG) the greatest integer less than or equal to ARG INTEGER-PART(ARG) the integer part of ARG NUMVAL(ARG) the numeric value of an argument that contains leading spaces, sign, or decimal point
Exercise #15
Using Exercise #10 and intrinsic functions, compute the minimum value of each row and the mean of the entire array.
Reconsidering Tables
With vast amounts of main storage today, you should consider the types of file operations you are using and whether or not an application could benefit by pulling an entire file (or part of a file) into main storage. Working directly with records in memory is very efficient and can speed up an application greatly Most of the time spent in an application is in I/O.
When a record is read from a file, defined with the RECORD IS VARYING IN SIZE.. DEPENDING ON ident phrase, the size of the record read into the buffer is moved into the data-item ident To write to a file, defined with the RECORD IS VARYING IN SIZE.. DEPENDING ON ident phrase, the size of the record to be written must first be moved to ident data-item, and then the WRITE statement must be executed.
Exercise #16
Use program WRITEVAR as a model. Run the program to create a variable length record file. Write a program READVAR that reads the file and prints out the total sales for each person
Strings
Joining Strings
Use STRING to join multiple parts of strings into an entirely new string
STRING ident1 literal INTO ident3 POINTER WITH OVERFLOW ON ident4 DELIMITED BY ident2 literal size
imperative stmt
Joining Strings
NOT
END-STRING
ID-4
ABC1234*5XYZ
STRING
STRING Operation
String does not replace rightmost character with spaces The POINTER field is a numeric field that afterwards contains the position of the next byte in the receiving field that would have been processed. (Max = string length + 1)
Exercise #17
Read the file DATA1. Create three fields in the input record: 1) cols 1 11 2) cols 15-18 3) cols 40-65 Remove the first part of field 1 up to the *. Remove all of field 2. Remove all of field 3 up to the first space String these three fields together. For example the first record would produce 66660066PEANUT Print the results of each record.
UNSTRING
UNSTRING
Extracts a field into multiple strings and stores them into one or more fields DELIMITED BY indicates how each subfield ends If ALL is specified for a delimiter, successive occurrences of the delimiter are treated as one
UNSTRING ADDRESS DELIMITED BY ALL INTO STATE ZIP WITH POINTER PTR END-UNSTRING
UNSTRING
UNSTRING copies Characters from the source string to the destination strings according to the rules for alphanumeric moves. UNSTRING uses space filling. The DELIMITED BY clause causes data movement from the source string to the current destination string to end when 1) a delimiter is encountered in the source string 2) the end of the source string is reached.
UNSTRING
If DELIMITED BY is not used, data movement terminates when 1) the destination string is full 2) the end of the source string is reached The UNSTRING terminates when 1) All the characters in the source string have been processed 2) All the destination strings have been processed 3) An OVERFLOW condition is encountered when the pointer is pointing outside the source string.
UNSTRING EXAMPLE
UNSTRING ADDRESS DELIMITED BY ALL INTO STATE COUNT IN STCNT ZIP COUNT IN ZIPCNT WITH POINTER PTR END-UNSTRING
UNSTRING Example
UNSTRING ADDRESS DELIMITED BY "," INTO LINE(1) LINE(2) LINE(3) Line(4) TALLYING IN NOLINES END-UNSTRING.
Tallying leaves the number of receiving fields that receive data in the named variable
Exercise #18
Read the file DATA1. For each record in the file, UNSTRING field 1-11 into two parts (separate at the *). Print each part.
INSPECT Statement
INSPECT Statement
Formats
INSPECT has four formats: 1) TALLYING: used to count characters in a string. 2) REPLACING: used to replace a group of characters in a string with another group of characters. 3) TALLYINGREPLACING: combines both operations in one statement. 4) INSPECT CONVERTING: converts each of a set of characters to its corresponding character in another set of characters.
TALLYING
INSPECT LINE TALLYING ACOUNT FOR ALL A INSPECT LINE TALLYING XCOUNT FOR ALL X" AFTER INITIAL S" BEFORE INITIAL E".
REPLACING
INSPECT MYSTRING REPLACING ALL X BY Y" AFTER INITIAL A" BEFORE INITIAL Z INSPECT MYSTRING REPLACING ALL XXXX" BY ABCD AFTER INITIAL A BEFORE INITIAL P"
TALLYING REPLACING
INSPECT LINE TALLYING ACOUNT FOR ALL A REPLACING ALL X BY Y" AFTER INITIAL A" BEFORE INITIAL Z
CONVERTING
INSPECT MYTEXT CONVERTING "abcdefghijklmnopqrstuvwxyz TO "ABCDEFGHIJKLMNOPQRSTUVWXYZ
Pointers
Creating a Pointer
05 PTR USAGE IS POINTER. 05 A-PTR POINTER. These definitions create 4 byte fullwords capable of containing addresses of memory locations
Setting a Pointer
SET PTR TO ADDRESS OF X SET PTR1 TO PTR2
Exercise #19
Try running programs LINKED and LINKED1 in BCST.SICCC01.PDSLIB
VSAM
VSAM data sets are known as Clusters For ESDS or RRDS the cluster consists of a data component For KSDS the cluster consists of a data component and an index component VSAM data is stored on DASD in control intervals which are grouped into control areas
VSAM
The Control Interval (CI) is the unit of data that transfers between the disk and virtual storage CI sizes are multiples of 2K with 4k being common CIs can be constructed with free space to accommodate additions to the file Control Areas (CA) can be constructed with free space to accommodate additions
VSAM
VSAM dynamically manages the file by maintaining information in each CI and CA When a CI becomes too full the data it contains is split into two CIs When a CA becomes too full the data it contains is split into two CAs VSAM tries to keep records that are logically close together, physically close as well
VSAM Indexes
VSAM Components
VSAM JCL
Unlike QSAM files, VSAM files must be allocated in a separate job step before data can be written to the file VSAM cluster can be created by deleting and then defining the cluster After the cluster is defined, a job can run which writes data to the file
VSAM JCL
Parameters:
INDEXED KSDS NONINDEXED ESDS NUMBERED RRDS KEYS ( len off) primary key info CISZ (size) control interval size FREESPACE (ci ca) free space %s
MAKEKSDS
000100 //TSYSAD2C JOB 'YOUR NAME',USER=TSYSAD2,REGION=2048K,MSGCLASS=V 000200 //*MAIN CLASS=TSYSC,USER=TSYSAD2 000300 //DEFINE EXEC PGM=IDCAMS 000400 //SYSPRINT DD SYSOUT=* 000500 //SYSIN DD * 000600 DELETE TSYSAD2.PAYROLL.MASTER 000700 DEFINE CLUSTER 000800 (NAME(TSYSAD2.PAYROLL.MASTER) 000900 INDEXED 001000 RECORDSIZE(31 31) 001100 KEYS(5 0) 001200 MGMTCLAS(STANDARD) 001210 FREESPACE(0 0) 001220 SHAREOPTIONS (3 3)) 001230 DATA (NAME(TSYSAD2.PAYROLL.MASTER.DATA) 001240 TRK(1 1) 001250 CONTROLINTERVALSIZE(4096)) 001260 INDEX (NAME(TSYSAD2.PAYROLL.MASTER.INDEX) 001270 TRK(1 1)) 001280 /*
IDCAMS PRINT
000100 //TSYSAD2P JOB 'A.STUDENT',USER=TSYSAD2,REGION=2048K,MSGCLASS=V 000200 //*MAIN CLASS=TSYSC,USER=TSYSAD2 000210 //* THIS IS AN IDCAMS PRINT 000220 //PRINT EXEC PGM=IDCAMS 000230 //SYSPRINT DD SYSOUT=* 000240 //SYSIN DD * 000250 PRINT INFILE(IFILE) 000251 DUMP 000252 /* 000253 //IFILE DD DSN=TSYSAD2.PAYROLL.MASTER,DISP=SHR 000254 //
IDCAMS REPRO
000100 //TSYSAD2R JOB 'A.STUDENT',USER=TSYSAD2,REGION=2048K,MSGCLASS=V 000200 //*MAIN CLASS=TSYSC,USER=TSYSAD2 000210 //* THIS AN IDCAMS REPRO 000220 //REPRO EXEC PGM=IDCAMS 000230 //FILEIN DD DSN=TSYSAD2.PGM1.RESULTS,DISP=SHR 000240 //FILEOUT DD DSN=TSYSAD2.I10.PGM1.RESULTS,DISP=(NEW,CATLG,DELETE), 000250 // UNIT=SYSDA,DCB=(RECFM=FB,LRECL=80), 000251 // SPACE=(TRK,(1,1),RLSE) 000252 //SYSIN DD * 000253 REPRO 000254 INFILE(FILEIN) 000255 OUTFILE(FILEOUT) 000256 /* 000257 //AMSDUMP DD SYSOUT=* 000258 //
OPEN
OPEN INPUT file-name OPEN OUTPUT file-name OPEN I-O file-name OPEN EXTEND file-name For EXTEND, access mode must be sequential
Writing
WRITE record-name [FROM data-name] [INVALID KEY imperative stmt] [NOT INVALID KEY imperative stmt] [END-WRITE]
REWRITE
REWRITE record-name [FROM data-name] [INVALID KEY imperative stmt] [NOT INVALID KEY imperative stmt] [END-REWRITE] A typical scenario is to read the record, modify it (cant change the key field), and then rewrite it. For random and dynamic access, you can REWRITE a record without first reading it.
DELETE
DELETE file-name [RECORD] [INVALID KEY imperative stmt] [NOT INVALID KEY imperative stmt] [END-DELETE] DELETE can only be used for a file in I-O mode If file is in sequential mode, the DELETE can only be used after executing a READ statement for that record. (Omit INVALID KEY) If file is in random or dynamic mode, a DELETE can be issued without previously reading the record (specify INVALID KEY)
START
START file-name KEY IS EQUAL TO data-name = GREATER THAN > NOT LESS THAN NOT < >= [INVALID KEY imperative stmt] [NOT INVALID KEY imperative stmt] [END-START] Used for sequential and skip-sequential processing Does not return a record positions you in the file
Exercise #20
Create a data file of records which is sorted on a key field (choose a 5 byte key). Creating an 80 byte record in a PDS is easiest. Let some of the keys be in the 10000 19999 range, some in range 20000 29999, some in range 30000 39999, and some in range 40000-49999. (VSAMDATA) Read the file and output a fixed size record VSAM file.
Exercise #21
Read the VSAM file you created in Exercise 20 and print out the records (your choice of format).
Exercise #22
Create a small file of keys. Some of the keys should match records in your VSAM file and some should not. (VSAMKEYS) Process the VSAM file randomly. Take each key, print it, and print the record if it is on the file, otherwise print a message indicating the record was not found.
Exercise #23
Process the VSAM file dynamically with skip-sequential processing. Issue a Start statement and print the records with keys in the range 2000029999. Issue another START and print the records in the range 40000 49999.
Exercise #24
Create a small file of keys. Some of the keys should match records in your VSAM file and some should not. Process the VSAM file randomly. Take each key, read the VSAM file, and delete each record that is found. If the record is not found print a message indicating this.
Alternate Indexes
An alternate index provides a way to navigate through a VSAM cluster using an alternate key Creating an alternate index is a 3 step process:
DEFINE ALTERNATE INDEX DEFINE PATH BLDINDEX
Define Alternateindex
//KC02107X JOB 'WOOLBRIGHT',REGION=2M,MSGCLASS=Q,MSGLEVEL=(0,0), // NOTIFY=KC02107 //*----------------------------------------------------------* //* VSAM //*----------------------------------------------------------* //STEPMAKE EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * DELETE KC02107.SICCC01.MYVSAM.AIX DEFINE ALTERNATEINDEX (NAME (KC02107.SICCC01.MYVSAM.AIX) RELATE (KC02107.SICCC01.MYVSAM) KEYS (20 5) NONUNIQUEKEY UPGRADE REUSE ) DATA (NAME (KC02107.SICCC01.MYVSAM.AIX.DATA) TRACKS(1 1)) INDEX (NAME (KC02107.SICCC01.MYVSAM.AIX.INDEX)) DEFINE PATH (NAME(KC02107.SICCC01.MYVSAM.PATH) PATHENTRY(KC02107.SICCC01.MYVSAM.AIX) UPDATE ) //
BLDINDEX
//KC02107X JOB 'WOOLBRIGHT',REGION=2M,MSGCLASS=Q,MSGLEVEL=(0,0), // NOTIFY=KC02107 //*----------------------------------------------------------* //* VSAM BLDNDX CLUSTER * //*----------------------------------------------------------* //STEPMAKE EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * BLDINDEX INDATASET(KC02107.SICCC01.MYVSAM) OUTDATASET(KC02107.SICCC01.MYVSAM.AIX) /* //
VSAM REPRO
//KC02107X JOB 'WOOLBRIGHT',REGION=2M,MSGCLASS=Q,MSGLEVEL=(0,0), // NOTIFY=KC02107 //*----------------------------------------------------------* //* VSAM REPRO CLUSTER * //*----------------------------------------------------------* //STEPMAKE EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * REPRO INDATASET(KC02107.ASM.DAT(VSAMDATA)) OUTDATASET(KC02107.SICCC01.MYVSAM) /* //
Debugging
Binary to Hex
Conversion rule: Remove blocks of 4 binary digits and replace them with a single hex digit 1101 1100 0011 1011 D C 3 B Hex dumps are made of hex digits and represent binary values that are stored in memory a short-hand notation 2 HEX DIGITS = 1 BYTE
EBCDIC Characters
CHAR 0 = 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = HEX F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 CHAR HEX A = C1 B = C2 C = C3 D = C4 E = C5 F = C6 G = C7 H = C8 I = C9 COMMA = 6B CHAR J K L M N O P Q R HEX = D1 = D2 = D3 = D4 = D5 = D6 = D7 = D8 = D9 CHAR S T U V W X Y Z = = = = = = = = HEX E2 E3 E4 E5 E6 E7 E8 E9
SPACE = 40 MINUS = 60
PERIOD = 4B
* = 5C
Packed Decimal
PIC S999 PACKED-DECIMAL VALUE 123 123C PIC S9(3)V99 PACKED-DECIMAL VALUE -123 00123D PIC S9(4) PACKED-DECIMAL VALUE -98 00098D PIC 9(7) PACKED-DECIMAL VALUE -32 COMPILE ERROR PIC 9(7) PACKED-DECIMAL VALUE 32 0000032C
Binary Data
1-4 digits = 2 bytes = halfword 5-9 digits = 4 bytes = fullword 10-18 digits = 8 bytes = doubleword PIC S9(4) BINARY = 2 BYTES PIC S9(5) BINARY = 4 BYTES PIC S9(9) BINARY = 4 BYTES PIC 9(8) BINARY = 4 BYTES
Signed Binary
Signed binary data is stored in 2s complement format High order bit is a sign 1 is negative, 0 is positive 0001101 = 13 in decimal 1110010 = -14 Conversion rule: Change the 1s to 0s and 0s to 1s, then add 1. This computes the 2s complement
Pointers
USAGE IS POINTER A 4 BYTE FULLWORD STORED IN BINARY
Signed Binary
Example: 111111 Changing: 000000 Add 1: 000000 + 1 = 000001 1 is the complement so 111111 is -1 Example: 110011 Changing: 001100 Add 1: 001100 + 1 = 001101 = 13 110011 = -13
Display
The answer to all debugging problems is to gain more information. DISPLAY can provide it.
Dump Information
<H1> I B M F A U L T A N A L Y Z E R S Y N O P S I S A system abend 0C4 reason code X'4' occurred in module IGZCPAC at offset X'3FEB4'. A program-interruption code 0004 (Protection Exception) is associated with this abend and indicates that: An attempt was made to access a protected storage location using an incorrect storage access key. The cause of the failure was program BOMB1 in module BOMB1. code that immediately preceded the failure was: Source Line # -----000027 The COBOL source
DISPLAY NAME
Dump Information
******************************************************************************** *********************** P O I N T O F F A I L U R E ********************** ******************************************************************************** This is the point where control left program BOMB1 prior to the S0C4 abend. COBOL Source Code: Source Line # ------5 05 NEXT-ANIM PIC X. -4 PROCEDURE DIVISION. -3 SET PTR TO ADDRESS OF MYTABLE-VALUES -2 SET ADDRESS OF ANIMAL TO PTR -1 PERFORM 7000 TIMES 000027 DISPLAY NAME +1 SET ADDRESS OF ANIMAL TO ADDRESS OF NEXT-ANIM +2 END-PERFORM +3 GOBACK
Dump Information
Load Module Name. . . . . . : BCST.GP5CS4.DOMESTIC.LOADLIB(BOMB1) At Address. . . . . . . . : 38B00C38 Load Module Length. . . . : X'13C8' Link-Edit Date and Time . : 2005/05/13 12:36:33 Program and Entry Point Name: BOMB1 At Address. . . . . . . . : 38B00C38 (Module BOMB1 offset X'0') Program Length. . . . . . : X'77A' Program Language. . . . . : COBOL (Compiled using IBM Enterprise COBOL for z/OS and OS/390 V3 R3 M1 on 2005/05/13 at 12:36:32) Machine Instruction . . . . : 05EF BALR R14,R15 At Address. . . . . . . . : 38B0106E (Program BOMB1 offset X'436') AMODE . . . . . . . . . . : 31 General Purpose Registers: R0: 00001364 (Storage invalid) R1: 38B00E49 (Module BOMB1 program BOMB1 + X'211')
Dump Information
WORKING-STORAGE SECTION Off Hex Value EBCDIC Value Source (Starting at ---- ----------------------------------- ------------------ -------------------<H5> BLW=0000 at address 38D500B8 01 MYTABLE-VALUES. 0 C1C1D9C4 E5C1D9D2 40404040 40 *AARDVARK * 10 PIC X(1 10 00000000 *.... * 10 MYPTR1 14 C2C5C1E5 C5D94040 40404040 40404040 *BEAVER * 10 PIC X(1 24 C3D6D5C4 D6D94040 40404040 40404040 *CONDOR * 10 PIC X(1 34 C4C5C5D9 40404040 40404040 40404040 *DEER * 10 PIC X(1 44 C5D3C5D7 C8C1D5E3 40404040 40404040 *ELEPHANT * 10 PIC X(1 54 C6D6E740 40404040 40404040 40404040 *FOX * 10 PIC X(1 64 C7C9D9C1 C6C6C540 40404040 40404040 *GIRAFFE * 10 PIC X(1 78 12345D -123.45 01 X PIC S99 80 F4F5C6 456+ 01 Y PIC S99 88 FFEC -20 01 Z PIC S9( 90 38D500B8 *.N.. * 01 PTR POINTER
Dump Information
LINKAGE SECTION BLL=0000 has not been assigned an address Off Hex Value EBCDIC Value Source (Starting at ---- ----------------------------------- ------------------ ------------------<H5> BLL=0001 at address 38D57FF8 01 ANIMAL. 0 00000000 00000000 00000000 00000000 *................* 05 NAME 10 00 *. * 05 NEXT-ANIM See "System-Wide Information" - "Storage Areas" - "Hex-Dumped Storage" for unformatted storage areas related to this event.
Dump Information
dress 38D500B8 01 9D2 40404040 40 040 040 040 5E3 040 540 40404040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 40404040 *AARDVARK *.... *BEAVER *CONDOR *DEER *ELEPHANT *FOX *GIRAFFE -123.45 456+ -20 *.N.. * * * * * * * * 01 01 01 01 MYTABLE-VALUES. 10 PIC X(13) VALUE "AARDVARK 10 MYPTR1 POINTER SYNC. 10 PIC X(16) VALUE "BEAVER 10 PIC X(16) VALUE "CONDOR 10 PIC X(16) VALUE "DEER 10 PIC X(16) VALUE "ELEPHANT 10 PIC X(16) VALUE "FOX 10 PIC X(16) VALUE "GIRAFFE X PIC S999V99 PACKED-DECIMAL Y PIC S999 VALUE 456. Z PIC S9(4) BINARY VALUE -20 PTR POINTER.
XML
XML = Extensible Markup Language Used to expose the structure and content of a document Becoming a universal means of exchanging data Tag language <author> <firstname>Charles</firstname> <lastname>Dickens</lastname> </author>
XML
Tags are user-defined Every start tag has a matching stop tag <atag> </atag> Sometimes the tags are combined into one start and stop tag <media type = CD /> Tags cant overlap NO: <a> <b> </a> </b>
XML
Tags can be nested <a> <b> </b> </a> Documents are tree-structured <a> <b></b> <c> <d></d> </c> </a>
a
XML
Text based documents Case sensitive Must contain one root element Start with an XML declaration and comments <?xml version = 1.0?> <! comment line - -> <a> </a>
XML
XML is Well Formed if 1) Single root element 2) Start and end tags matching for all elements 3) Proper nesting 4) Attribute values in quotes
XML Parsers
An XML parser is a program that can read an XML document and provide programmatic access to the document Two types of parsers: 1) DOM based Document Object Model Constructs a tree that represents the document 2) SAX based Simple API for XML Generates events when parts of the document are encountered. Can also be classified as push or pull parsers
Enterprise COBOL
Contains an event-based parser that allows you to read XML documents and process them with COBOL XML documents can be retrieved from an MQ message, CICS TD queue, or IMS message processing queue XML documents that are read from a file must be brought into storage as a single item. (Records can be combined using STRING)
Parsing
XML PARSE document PROCESSING PROCEDURE event-handler-name ON EXCEPTION NOT ON EXCEPTION END-XML Parsing continues until 1) an END-DOCUMENT event occurs 2) the parser signals EXCEPTION and the procedure doesnt reset the XML-CODE register to 0 3) you terminate processing by moving -1 to XMLCODE
Events
Some typical events: START-OF-DOCUMENT START-OF-ELEMENT ATTRIBUTE-NAME END-OF-ELEMENT CONTENT-CHARACTERS START-OF-CDATA-SECTION END-OF-DOCUMENT
Processing Flow
Exercise #25
Use the file BCST.SICCC01.PDSLIB(XMLDATA2) The file structure is similar to the one below:
<?xml version=1.0 encoding=ibm-1140 standalone=yes?> <batch> <trans> <name>Joe Smith</name> <amt>12.32</amt> <amt>5.42</amt> </trans> <trans <name>Tina Louise</name> <amt>8.99</amt> </trans> </batch
Exercise #25
Write an XML Cobol program that reads the file and copies it to memory. Print out a report that lists each customer name and a total for each customer. Print a grand total for the entire file Name Amount Joe Smith 17.74 Tina Louise 8.99 Grand Total 26.73
Exercise #26
Read the file BCST.SICCC01.PDSLIB(BOOKLIST) Copy the data into memory storing the data as a Cobol data structure Write out the entire file as a single XML file Pretty print the XML file
Exercise #26
The XML file should have the following structure <booklist> <book> <author>Melville</author> <title>Moby Dick</title> </book> . </booklist>
Compiler Options
Default compiler options are in effect for TSYS Options can be overridden with a process statement that precedes the IDENTIFICATION DIVISION Example (Start in column 8 or 1)
PROCESS LIST, AWO
NUMPROC
NUMPROC(PFD) generates efficient code for numeric comparisons. Doesnt fix up signs NUMPROC(NOPFD) causes sign fix up for numeric fields NUMPROC(MIG) causes arithmetic similar to OS/vs Cobol
OPTIMIZE
OPTIMIZE(STD) and OPTIMIZE(FULL) - eliminate unnecessary brancing - simplifying inefficient branching - simplifying the code for out-of-line PERFORM, moving the code in-line - simplifying calls to nested programs - eliminating duplicate computations - eliminating constant computations - aggregating MOVES - deleting unreachable code - deleting unreferenced data items (FULL only)
OPTIMIZE
NOOPTIMIZE suppresses optimizations Helpful during development to speed compilations Better for testing because code is not removed OPTIMIZE for production
RMODE
RMODE(AUTO) + RENT = RMODE(ANY) RMODE(AUTO) + NORENT = RMODE(24) RMODE(24) + NORENT => WS below the line RMODE(ANY) + NORENT => WS is above the line
TRUNC
TRUNC(BIN) Causes base 2 truncation on some intermediate calculations to insure the answer conforms to a halfword, fullword, or doubleword boundary TRUNC(STD) Causes base 10 truncation on some intermediate calculations TRUNC(OPT) Assumes the data conforms to the PICTURE and USAGE clauses and manipulates the result based on the size of the field in storage
ARITH
ARITH controls the number of digits in decimal numbers (packed, zoned) ARITH(EXTEND) is slower than ARITH(COMPAT) - COMPAT <= 18 digits - EXTEND max 31 digits
Performance Issues
CALLs Nested faster than static, call literal faster than dynamic call literal, call literal faster than dynamic all identifier, dynamic call literal faster that dynamic call identifier Nested calls are the fastest and there are good program design reasons for using them as well
Performance Issues
IS INITIAL on PROGRAM-ID can be very penalizing in terms of time QSAM files - BLOCK CONTAINS 0 RECORDS ! - Experiment with more buffers by modifying the RESERVE clause of the SELECT statement or specifying more buffers in JCL (BUFNO) - Code APPLY WRITE-ONLY or use AWO compiler option for variable length blocked files
Data Types
BINARY (COMPUTATIONAL)
PIC S9(N) BINARY N is from 1 to 4 Halfwords N is from 5 to 8 Fullwords N is 9 fullword data converted to doublewords - SLOWER! N is 10 to 17 Double words SLOW N is 18 converted to a higher precision format SLOWEST!
Data Types
PACKED-DECIMAL (COMP-3) use 15 or few digits in the PIC clause to avoid the use of library routines. Always code an odd number of digits! Always code a sign unless you have a good reason not to.
Performance Issues
Specify SYNCH for BINARY items. Use signed data items with 8 or fewer digits S9(8) BINARY SYNC S9(4) BINARY SYNC 9 or more digits is slower 18 digits is slowest Avoid USAGE IS DISPLAY for numeric fields PIC S99.
Performance Issues
Use 15 or fewer digits for PACKEDDECIMAL (COMP-3) fields Always code a sign (S) unless you have a programmatic reason not to. S9(8) instead of 9(8). Indexes are faster than subscripts If you choose subscripts code S9(8) BINARY SYNC or better yet, choose indexes instead
Performance Issues
Use PIC S9(8) BINARY fields for loop control variables Packed-decimal fields are slower Display fields (PIC 999) are slowest! Initialize constants with a value clause and dont modify them or pass them by reference. (Compile will optimize the constants.)
Performance Issues
Dont use PERFORM THRU Make appropriate use of in-line PERFORMS Try to use tables so the rightmost subscript varies the most often. (Compiler can optimize some subscript calculations) Use SEARCH ALL for tables with 100 items or more