Posted: Wed Dec 08, 2004 3:08 am Post subject: Copy Last 50 records from a file
let us take a file that contain some number of records and the exact number of records are not known and if i want to copy the last 50 records how can we do it
Note: Title edited by the moderator and moved to the JCL forum
Joined: 07 Jan 2003 Posts: 1056 Topics: 91 Location: The Blue Planet
Posted: Wed Dec 08, 2004 5:04 am Post subject:
Keshav,
Please follow the Forum rules. "Please provide a Relevant Title for your question". JCL has no meaning / relevance to your question.
Ok....There are couple of ways to do this, especially using SORT.
Solution 1: Sort (Pretty old version of Syncsort that does not support REMOVECC Parm). If your shop has DFSORT replace SYNCTOOL by ICETOOL and run ur code.
Code:
//R010 EXEC PGM=SYNCTOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//INPUT DD *
ONE
TWO
THREE
FOUR
FIVE
SIX
SEVEN
EIGHT
NINE
TEN
ELEVEN
TWELVE
/*
//TEMP DD DSN=&&T1,DISP=(,PASS)
//CTL3CNTL DD DSN=&&T2,DISP=(,PASS)
//OUTPUT DD SYSOUT=*
//TOOLIN DD *
COPY FROM(INPUT) TO(TEMP) USING(CTL1)
COPY FROM(TEMP) TO(CTL3CNTL) USING(CTL2)
COPY FROM(INPUT) TO(OUTPUT) USING(CTL3)
/*
//CTL1CNTL DD *
OUTFIL TRAILER1=(COUNT),
NODETAIL
/*
//CTL2CNTL DD *
INREC FIELDS=(C' SKIPREC=',2,8,FS,SUB,+5,EDIT=(TTTTTTTT))
/*
Brief Description:
The OUTFIL TRAILER1=(COUNT) will give the count of records in the input file. NODETAIL parm will suppress the actual records from being written to the output. After getting the count, subtract 5 (just for example, you need to use 50 as per ur requirement) from the count & generate a small Sort control card which uses SKIPREC=n to skip first (count - 50) records.
Solution 2: If you have DFSORT or a bit latest version of Syncsort which supports REMOVECC parm of TRAILER1. Use this.
Code:
//R010 EXEC PGM=SYNCTOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//INPUT DD *
ONE
TWO
THREE
FOUR
FIVE
SIX
SEVEN
EIGHT
NINE
TEN
ELEVEN
TWELVE
/*
//CTL2CNTL DD DSN=&&T2,DISP=(,PASS)
//OUTPUT DD SYSOUT=*
//TOOLIN DD *
COPY FROM(INPUT) TO(CTL2CNTL) USING(CTL1)
COPY FROM(INPUT) TO(OUTPUT) USING(CTL2)
/*
//CTL1CNTL DD *
INREC FIELDS=(1,80,
SEQNUM,8,ZD)
OUTREC FIELDS=(c' SKIPREC=',81,8,ZD,SUB,+5,EDIT=(TTTTTTTT),80:X)
OUTFIL TRAILER1=(1,80),REMOVECC,NODETAIL
/*
Brief Description:
Assuming your input file is of length 80 & RECFM=FB, I included 8 digit SEQNUM (Sequence Number) at the end of layout. Then in OUTREC the record the sequence numbers are subtracted from 5 (You need to use 50). Finally OUTFIL TRAILER1 writes only the last record which contains the actual value (record count - 5) i.e., seqnum of last record (which is same as record count) - 5.
When u use OUTFIL TRAILER the output is generated as FBA and an Ansi char is inserted in col 1. REMOVECC is used to remove that.
Brief Description:
1. Using INREC generate 8 digit sequence numbers. (Note: Input Data is not copied here)
2. Sort the records in descending order of Sequence no.
3. Pick up the first record in descending order (which is actually the last record of the actual file) and Subtract the required no. of records (50 as per your requirement) from the sequence no.
4. Generate a dynamic sort control card which will have SKIPREC=n (where n is the output of the subtraction).
Joined: 26 Nov 2002 Posts: 12375 Topics: 75 Location: San Jose
Posted: Thu Dec 09, 2004 6:30 am Post subject:
Phantom,
Here is a slight modification of your job. Since you are already sorting, you don't need to generate the CTL2 control card once again. In the first pass itself write out the last 50 records using the endrec feature. Now you have the records in reverse order. All you need is another sort on seqnum ascending so that the original order is retained. You also don't need the sysout and sysprint datasets.
Joined: 07 Jan 2003 Posts: 1056 Topics: 91 Location: The Blue Planet
Posted: Thu Dec 09, 2004 6:48 am Post subject:
Kolusu,
Now we have one more solution to accomplish the same task !!!.
I did not see the SYSPRINT & SYSOUT in my post. I just copied & pasted my friend's solution!. Thanks a lot for pointing it out.
Btw, Actually I advised my friend to minimize the no. of SORTs as much as possible, b'cas COPY is much faster than the SORT operation. It does not matter much for smaller files but in my perception, we should always think of efficiency so that we can get a better solution (if not the best). I'm just following ur foot steps Kolusu.
Joined: 02 Dec 2002 Posts: 1618 Topics: 31 Location: San Jose
Posted: Fri Dec 24, 2004 11:47 am Post subject:
With z/OS DFSORT V1R5 PTF UQ95214 or DFSORT R14 PTF UQ95213 (Dec, 2004), you can now use COUNT-n=(edit) in the TRAILERx parameter to do this more easily with a DFSORT/ICETOOL job like this:
This is a version of the job phantom showed earlier with some needed corrections (' OPTION SKIPREC=' and FNAMES=CTL2CNTL). _________________ Frank Yaeger - DFSORT Development Team (IBM)
Specialties: JOINKEYS, FINDREP, WHEN=GROUP, ICETOOL, Symbols, Migration
DFSORT is on the Web at:
www.ibm.com/storage/dfsort
This is used to design the conrol card, but I am bit confused about the parameters which was given.
TTTTTTTT - The no: of records (ex : 00000004)
FS - ??? ( This is edit pattern, but want to more about this)
2,8 - The control card starting position ( Is it?)
Thanks in Advance !!! _________________ Regards
Hari
Joined: 02 Dec 2002 Posts: 1618 Topics: 31 Location: San Jose
Posted: Fri Dec 24, 2004 5:30 pm Post subject:
Hari,
You didn't say, but I guess your question is directed to Phantom since you're asking about the INREC statement in his post - right? _________________ Frank Yaeger - DFSORT Development Team (IBM)
Specialties: JOINKEYS, FINDREP, WHEN=GROUP, ICETOOL, Symbols, Migration
DFSORT is on the Web at:
www.ibm.com/storage/dfsort
1. COPY FROM(INPUT) TO(TEMP) USING(CTL1)
The sort control card CTL1 uses the OUTFIL TRAILER feature to get the record count of input file. NODETAIL parm will suppress the input records from being written to the output file. So the output file will contain only 1 record with the record COUNT. Since we have a old version of SYNCSORT, REMOVECC parm of TRAILER is not supported here. Hence the output file is created as FBA instead of FB as shown below.
Assuming we have 12 records in the input file, the temp. file is created as shown below. The character '1' in col 1 is the print control character (for FBA file). The COUNT is displayed as ZZZZZZZ9 - 8 digit count with leading zeroes suppressed.
Code:
----+----1----+----2
1 12
2. COPY FROM(TEMP) TO(CTL3CNTL) USING(CTL2)
Now, the control card CTL2 takes this COUNT from positions 2 thru' 9 and subtracts '5' from it. By default the arithmetic operations like ADD,SUB,DIV,MUL will write the output in 15 digit ZD format. I then applied the EDIT pattern (TTTTTTTT - same as COBOL 99999999) to truncate the 15 digit result to 8 digits with leading zeroes RETAINED.
The next question will be about 'FS'. When ever we do an arithmetic operation, we need to inform sort about the data type of source fields. Here the source field is the count in positions 2 thru' 9. FS is used to indicate sort that the source field is numeric EDITED with leading zeroes suppressed.
Hope my explanation was clear. Please let me know if you have any questions,
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum