View previous topic :: View next topic
|
Author |
Message |
venuhunev
New User
Joined: 26 May 2007 Posts: 70 Location: chennai
|
|
|
|
Hi,
I have a problem in reading a variable file in a COBOL program which uses copybook having multiple layouts.
My actual file record length is 151 (155 in JCL) and Block size is 23467. since the file is existing and cannot change attributes, I am not sure how to solve it.
No Abends or any other errors. I am splitting detail 1 and detail 2 record along with header record. So I just read it and direct the input to specific output.
Following is an example of the problem what I face.
Quote: |
Copybook layouts:
Code: |
01 Record
05 gen-record pic x(45).
01 Header.
05 hdr-record pic x(20).
01 Detail1
05 dtl1-record pic x(25).
01 Detail2
05 dtl2-record pic x(35).
01 Trailer.
05 TRL-record pic x(20).
|
When I read the input file in program record by record, i am getting few details from next record as well (bolded ones below are from next records)
Input file:
Code: |
0ASD11 20120112 11100
11232134123 123zecv 123123123
2123124212312323 123231 asdasdsad
999999 20120112 1234569978 |
When I read and displayed the first record in the program,
0ASD11 20120112 1110011232134123 123ze
Second record is displayed as
11232134123 123zecv 123123123212312421
Third record is displayed as
2123124212312323 123231 asdasdsad99999
Last record is displayed correctly as there are not more records further.
999999 20120112 1234569978 |
My guess is because of Block size. But I am not sure.
Kindly help me to overcome this while reading. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
What are you DISPLAYing?
With multiple types of record, you should have something on the record to tell you which layout to use. If you use the wrong layout to DISPLAY a particular record, then you well get more/less data shown than expected (sometimes, when lucky, a S0C4).
Nothing to do with anything except defining more/less data than exists (ie using the wrong record-layout, ie coding error - at least from what you have explained so far). |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8700 Location: Dubuque, Iowa, USA
|
|
|
|
As Bill says, depending upon what -- exactly -- you are doing, it does not appear there's an error or even anything to change. The system fills the buffer when it does a read; if your COBOL program attempts to reference data past the length of the currently defined record then you'll see data from the next record(s). This behavior is the way COBOL works and has worked for many, many, many years -- so there's not much chance you are going to be able to change it. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Just to add, you blocksize is not very good for a 3390 track. Wasting 10k per track, or close to 1/6 of the space available. |
|
Back to top |
|
|
venuhunev
New User
Joined: 26 May 2007 Posts: 70 Location: chennai
|
|
|
|
I am displaying all 01 variables when reading each record.
READ INFILE.
DISPLAY RECORD.
DISPLAY HEADER.
DISPLAY TRAILER.
DISPLAY DETAIL1.
DISPLAY DETAIL2. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Well, there's your problem.
I don't know what RECORD represents, presumablye you've carefully hidden the real name from us, as RECORD is a reserved word, but the other record areas would seem to relate to the first byte of data.
So, 88 for the first byte
Code: |
evaluate true
when 88-says-detail-1
display detail1
when 88-says-detail-2
display detail2
when 88-says-header
display header-record
when 88-says-trailer
display header-record
when other
whoops, theres something unusual here
end-evaluate |
Your FD, in this case, is getting to look at the whole block of data, and there will be a number of buffers/blocks following. When you "read" a record, if there is data left in the block, your FD will just be pointed to it. If the block is finished but other blocks have already been read, you will be pointed to the first record in the next block. If all blocks/buffers have been "read", a new physical read will be done to get the next set of blocks/buffers for you, and you will be pointing to the first record in the first block.
If you are using a record layout longer than the current record, you will "see" the begining of the next record, possibly in the next block/buffer.
Basically, don't do it. Only use the record layout which matches the current record. |
|
Back to top |
|
|
venuhunev
New User
Joined: 26 May 2007 Posts: 70 Location: chennai
|
|
|
|
Thanks for your replies.. sorry, I have edited my reply.
I actually dont need display in my code. I just did it to know what was wrong.
My file is Variable (151). Atleast one of the record layout should be 151. So I have a 01 varaible which is RECORD.
File Structure:
header record layout is 40
detail1 record layout is 50+10 (where last 10 bytes are not mandatory kinda comments)
detail2 record layout is 40
Trailer record is 40.
When i execute READ INFILE for the first time, it takes 40 bytes of HEADER record as the layout is for 40 bytes.
But my detail1 record layout varies as the last 10 bytes are not mandatory. so my detail1 record could be 50 bytes or 55 bytes.
Consider my first detail1 record which is 50 bytes, but my read statement populates 50 bytes from first detail1 record and 10 bytes of next record. |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
all you have provided us is the info that you have no idea what is going on.
you need to provide, FD, i/o statements (at a minumum)
before anyone can provide you with the info that you need. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
We didn't really expect that you were only interested in DISPLAY. The comments apply to the records, not to any Cobol verbs.
You started off by telling us you had multiple layouts in a copybook. What you showed were different sizes, so you'd have a variable-length-record file.
Now, possibly, you are telling us that the records themselves can also be different lengths but the same type.
If that is what you mean, then there must be something on the record which distinguishes between the "fixed" part of the record for a particular type and the "variable" part, and within the fixed part there should be something which, usually indirectly, indicates the length (as in presence) of the variable part.
If you have 10 bytes which are there sometimes and not there at others, there must be something to indicate that. Only access the extra 10 bytes when the "something" is true. |
|
Back to top |
|
|
venuhunev
New User
Joined: 26 May 2007 Posts: 70 Location: chennai
|
|
|
|
FD INFILE
LABEL RECORDS ARE STANDARD
RECORDING MODE IS V
BLOCK CONTAINS 0 RECORDS
RECORD 151 CHARACTERS.
COPY COPY1.
I gave 151 characters like FB. I think I should give RECORD VARYING 40 to 151. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
The shortest record you showed previously was 20 bytes.
If that is the FD you ran with, and managed to display all your records to the end, you'll not get much different if you do 20/40 to 151.
You have to use, in your program, every time, only the data which belongs to the current record.
To do that, you have to know the record type.
And if the record, by type, can be variable you have to know what tells you it is variable, and use that. Normally this would be an indicator or a count.
Only access the variable part if you know there is data there belonging to the current record.
Otherwise you will be copying data from the subsequent record(s) and even, on occasion, accessing storage you are not allowed to (possible when final record in final current block/buffer) and getting an S0C4.
Before looking at anything else, know which record it is, and use the correct layout.
Before looking at anything variable, know if/how many are present.
No problem, just normal stuff. |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19243 Location: Inside the Matrix
|
|
|
|
Hello,
READing INTO a working-storage variable that has redefines for each record type may help you reduce confusion(personally, i believe this is a better way to code also). |
|
Back to top |
|
|
Bill O'Boyle
CICS Moderator
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
|
|
|
|
Click here - www.ibmmainframes.com/viewtopic.php?p=191731&highlight=#191731
In the FD, you only need a single 01 area defined to the largest-length record.
As Dick has suggested, issue your READ into the largest WORKING-STORAGE area, defined to the largest maximum-length.
Then, check the value in WS-INPUT-LGTH and you'll know which type of record you have, because it will be set to the length of the record just read.
Once you've determined the record-length, you can them move it to the correct area. |
|
Back to top |
|
|
venuhunev
New User
Joined: 26 May 2007 Posts: 70 Location: chennai
|
|
|
|
thanks everyone for the suggestion... infact.. solution.... it worked |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19243 Location: Inside the Matrix
|
|
|
|
Good to hear it is working - thank you for letting us know
d |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Mmmm.... I was afraid of that.
You have a max record-length (data) of 147 bytes. For more than 100 bytes, with the definitions you have shown, you are effectively going to "guess" whether theres is something there or not.
For that extension, you have more than one field. If more than one field of those more than one fields is not there, then you are lost.
Good luck. |
|
Back to top |
|
|
|