Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

need help with variable length records 3

Status
Not open for further replies.

rlh145

Programmer
Feb 19, 2001
36
US
I am working with variable length records in a program for the first time in a very long time. I am not sure how to set up the FD statement and when I try what I think is right, I get error messages IGZ0201W and IGZ003355.

Does someone out there have some code that shows a variable length FD set up be willing to send me a copy of it? My address is Ralph.Harwood@ncmail.net And my last question is where can I find more explanation to the error messages I am getting?

Thanks!
Ralph

 
Ralph -

You don't indicate your environment. I assume it's MVS, but may also be VSE or VM. For information about the messages, you should check the IBM documentation. Here's what I found when I checked the IBM VSE online book manager stuff(
Code:
   IGZ0201W  A file attribute mismatch was detected. File file-name in program program-name had a record length of record-length-1 and the file specified in the ASSIGN clause had a record length of record-length-2.

Explanation: The program file description specified a record length that did not match the record length of the file associated with the ASSIGN clause. The OPEN statement failed. 

Programmer Response: For Format-V and Format-S files the maximum record length specified in your program must be exactly 4 bytes smaller than the length attribute of the file. For Format-F files, the record length specified in your program must exactly match the length attribute of the file. For Format-U files, the maximum record length specified in your program must exactly match the length attribute of the file. If your file is a printer file, the compiler may add one byte to the file description for carriage control character, depending on the ADV compiler option and the COBOL statements used in your program. In which case, the added byte must be included in the file length attribute. 

System Action: If a file status was specified, no system action is performed. If a file status field was not specified, the program is terminated and message IGZ0035S is generated. 
[\code]
Also, a quick search of [URL unfurl="true"]www.google.com[/URL] groups often turns up useful stuff when given just an error message number.  I found a couple of interesting threads about this message that way.

Most variable length files can be defined as:

[CODE]
FD  FILENAME-1
    RECORDING MODE V
    LABEL RECORDS ARE STANDARD
    BLOCK CONTAINS 0 RECORDS.
01  FILENAME-1-RECORD. etc.
[\code]
COBOL will determine the max and min record sizes from the record definition(s).

Good luck.

Glenn
Brainbench MVP for COBOL II
 
Hi Ralph,

Here's some other info that may be helpful. IBM Manuals are strangely silent on how to process variable and undefined records. I've been thinking about writing a FAQ on this subject, but there are some aspects that I'm not sure of. But here's what I do know.

There are three situations you can find yourself in when attempting to read/write variable records in a COBOL pgm:

1) Each record read contains a Rec type field that indirectly identifies the length of the rec read.

2) Each rec read contains one or more variable tables (they use the ODO clause) that vary the length of the rec. Therefore, you can't determine the exact length of the rec.

3) Each rec read does NOT contain variable tables, but are variable in length.

In all cases there is a dichotomy between the JCL and the program when the rec length/blksize is stated or implied.

Variable recs each contain a 4 byte Record Descriptor Word (RDW). If they are blocked, each block contains a 4 byte Block Descriptor Word (BDW). In each only the 1st 2 bytes contain the length. The other 2 are used for spanned recs.

So what this means is that your JCL rec length will be 4 bytes larger than the rec len stated or implied in the pgm. Similarly, the JCL max blksize will be 8 bytes larger than the Max blksize stated in the pgm.

OK, back to the situations:

In #1 code the FD with
Code:
RECORD CONTAINS x TO y
BLOCK CONTAINS 0 RECORDS.
The FD rec layouts (1 for each rec type) look something like this:
Code:
01 rec-1.
   05  rec-typ1     pix x.
   yada, yada, yada 

01 rec-2.
   05  rec-typ2     pix x.
   yada, yada, yada 
etc, etc.
You code the O/P file in a similar way, just choose names that make sense. I'll assume names prefixed by OP-.

In the PD:
Code:
    READ INPUT-FILE
    IF REC-TYPE1 = '4'
       PERFORM PROC-REC-TYP4
       PERFORM WRITE-REC-TYP4
    END-IF

PROC-REC-TYP4.
    .  
    .  
    .  
    MOVE REC-4 TO OP-REC-4
    WRITE OP-REC-4.
Note that the multiple 01s in the FD redefine each other, so referencing any "REC-TYPE" picks up the one just read.

Make sure you determine what rec you read by checking the rec-type. Use the same O/P rec type to write the rec.

Note also that if you want to save the MOVE, use:

WRITE OP-REC-4 from REC-4

In #2 and #3 code the FD with
Code:
RECORD VARYING x TO y DEPENDING ON WS-VLEN
BLOCK CONTAINS 0 RECORDS.
The FD rec layouts look something like this:
Code:
01  VAR-FILE-IP.
    05  VAR-BYTES-IP   PIC X OCCURS 1 TO X
                       DEPENDING ON WS-VLEN.
Optionally, you can code other 01s here.

In the WS code:
Code:
01  WS-VLEN  pic 9(005).
After you do the read, WS-VLEN will contain the length of the record just read. You use this length if you want to rewrite the record just read keeping the same length. If you want to change the rec length for the write, just recalculate it and move it to WS-VLEN before you perform the write.

Here's the part I'm not sure of:

If with situation #2, each rec read contains more than 1 variable table, I think you HAVE to use what I outlined above. On the otherhand, If the recs contain only one variable length table, you may be able to use the original record definition of the rec and use the ODO object field of that rescription in the FD RECORD VARYING clause. I THINK. I've never used it.

But as I said before, you can use the other approach and just include the additional description after the 1 byte ODO rec description.

The other thing I'm not sure of is whether this approach can be used for undefined (RECFM=U) reords.

Well, there it is. I hope I didn't make the waters muddier. :)

Regards, Jack.

 
I haven't worked on IBM mainframes recently, but I did use variable length records on IBM mainframes in COBOL and assembly for about 20-25 years.

The main thing to remember is the record descriptor word (RDW) at the beginning of each record, as mentioned in the above postings, is not described in the COBOL program. So the greatest record length defined in the COBOL program must be 4 bytes less than the actual greatest record length defined in the dataset descriptor (Catalog, VTOC, or tape label). Also, you should not specify a block size in the COBOL program. Note that you implicitly define a block size if you do NOT explicitly specify

BLOCK [CONTAINS] 0 [RECORDS]

The default is

BLOCK CONTAINS 1 RECORDS

Later versions of COBOL may (have) eliminate(d) this problem.

Methods of identifying the record length on input have been adaquately discussed in above postings. Note that the record length field explicitly referenced in the OCCURS DEPENDING ON data-name in the RECORD CONTAINS clause works for Undefined as well as Variable length records. It must be defined in WORKING-STORAGE or LINKAGE sections.

In newer versions of COBOL, you can also get the input record length using the LENGTH OF record-name syntax.

If you have an OCCURS DEPENDING ON (ODO) table in the record and it is not the last field with the same or lower level number in the record descriptor, regardless of whether the following fields are ODO, you've got problems.
The resulting internal representation is implementation defined and may vary according to the compiler options used.
DON'T DO THIS WITH ANY NEW FILES.

In writing variable-length records with ODO tables, you must explicitly update the object of the ODO before writing the record. i.e.

FD OUTPUT-FILE BLOCK 0.
01 OUTPUT-RECORD.
05 OUT-FAMILY-NAME PIC X(30).
05 OUT-FAMILY-SIZE PIC 9(02).
05 OUT-PERSON-NAME PIC X(20)
OCCURS 1 TO 15 TIMES DEPENDING ON OUT-FAMILY-SIZE.
.
.
.
WORKING-STORAGE SECTION.
01 WS-RECORD.
05 WS-FAMILY-NAME PIC X(30).
05 WS-FAMILY-SIZE PIC 9(02).
05 WS-FAMILY-NAME PIC X(20).
.
.
.
PROCEDURE DIVISION.
.
.
.
MOVE 15 TO OUT-FAMILY-SIZE.
MOVE WS-RECORD TO OUTPUT-RECORD.
MOVE WS-FAMILY-SIZE TO OUT-FAMILY-SIZE.
WRITE OUTPUT-RECORD.

The first MOVE above is to ensure that OUTPUT-RECORD is "long enough" to hold the largest record.

The third MOVE seems to be redundant, as the OUT-FAMILY-SIZE is updated by the second MOVE. But the complier doesn't "know" that, and doesn't generate the code to update the record size without the third move.
 
Two other points I neglected to mention in my original post:

1) When using variable recs in CICS move the max rec length the length variable of the READ stmt before issuing the stmt. The true length of the record just read will be returned in the length variable. When issuing a write move the desired length of the rec to the length variable of the WRITE stmt. If the length variable used in the FROM clause is the desired length of the record, no length variable is required for the WRITE stmt.

2) When creating a variable length BLOCKED file, the use of the AWO (Apply Write Option, I think) compiler option is advisable. To explain how it works, consider the following example:

(Take note that the discussion below ignores the RWD/BRW extensions and only deals with the length of the data portion of the recs)

You're creating a VB file w/2 possible rec lens: 100 and 1000. You choose a blksize of 1000 and the recs in the file are written in this sequence: 100,100,100,1000. I AWO is not specified, how many blocks of data are written? If you guessed 2, you'd be wrong. The system creates 4 blocks of data, 3 100-byte blocks and 1 1000 byte block.

When deciding to write a variable block, the system assumes that the next rec written will always be of the maximum length specified for the file. So, in the example, when attempting to write the 1st 100 byte rec, the system adds 1000 to the 100 byte length of the rec to be written and assumes the max blksize will be exceeded if the next rec is added to the block. It then proceeds to prepare to build the next block, reads the next 100 byte rec and proceeds in the same manner, creating a new block for every 100 byte rec in the file, as well as for the final 1000 byte rec.

AWO was introduced in recognition of the fallacy of this process defers the decision until it can determine the true end of the block. So, in the example the 1st 3 100 byte recs are accumulated into a block of 600 bytes and the 1000 byte rec represents the only other block written.

Why is this important? When the system writes blocks, it separates them with inter-record gaps (IRGs). These gaps occupy media space (tape or disk). The space occupied varies with the media used and the density with which it was written. The point is that for large files, cumulatively, this space can become substantial. In my view AWO should always be used for VB files, well worth the potential of increased processing time.

Regards, Jack.
 
Hi,

In general it helps to use a read into a working-storage definition, because it avoids troubles.

Also when you define one of the input records containing a PIC S9(4) COMP OCCURS 1 and use a subscriptor with value -1 to read the recordlength. If you use this, the compileroption should be set to NOSSRANGE and N O T TRUNC(STD). One of the ways to accomplish this is by using the CBL NOSSRANGE,TRUNC(OPT) statement in front of your source.

Regards,

Crox
 
I think most of this discussion is moot as the new COBOL standard is that the record area in the FD is not the actual I/O buffer, but an intermediate area. Also, it only applies to IBM mainframes with some operating system desending from OS/VS.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top