MVSFORUMS.com Forum Index MVSFORUMS.com
A Community of and for MVS Professionals
 
 FAQFAQ   SearchSearch   Quick Manuals   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Splitting a flat file using JCL

 
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Job Control Language(JCL)
View previous topic :: View next topic  
Author Message
seema patni
Beginner


Joined: 04 Nov 2003
Posts: 8
Topics: 5

PostPosted: Tue Nov 04, 2003 6:44 am    Post subject: Splitting a flat file using JCL Reply with quote

Hi ,

I want to know how to split a flat file into more than one file . How many files are to be made should be parameter driven .

Thanx
Seema
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12372
Topics: 75
Location: San Jose

PostPosted: Tue Nov 04, 2003 6:46 am    Post subject: Reply with quote

seema patni,

What is the split criteria? for ex: the input file has 1000 rows not that is to be split into 5 different files with 200 records each.

Let us know the details and we will able to help you

kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
seema patni
Beginner


Joined: 04 Nov 2003
Posts: 8
Topics: 5

PostPosted: Tue Nov 04, 2003 7:30 am    Post subject: Reply with quote

Hi,

For example let my input file have 1000 rec.. It could be split into 4 files in 2 ways

1. File1 having rec from 1 to 250
File2 having rec from 251 to 500
File3 having rec from 501 to 750
File4 having rec from 751 to 1000

2. File 1 : rec1, rec5, rec9 ....
File 2 : rec2, rec6, rec10...
File 3 : rec3, rec7, rec11...
File 4 : rec4, rec8, rec12...

I would like to know how above 2 can be achived. I can get only the input file. Can we achive the file split even if we don't know how many recs the input file has ?

Thanks and regards,
Seema
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12372
Topics: 75
Location: San Jose

PostPosted: Tue Nov 04, 2003 8:35 am    Post subject: Reply with quote

Seema,

The following JCL will split the input file into 4 different files in round robin fashion.

Code:

//STEP0100  EXEC  PGM=SORT
//SYSOUT    DD SYSOUT=*                                   
//SORTIN    DD DSN=YOUR INPUT DSN,               
//             DISP=SHR                                   
//OUT1      DD DSN=YOUR OUTPUT FILE1,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT2      DD DSN=YOUR OUTPUT FILE2,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT3      DD DSN=YOUR OUTPUT FILE3
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT4      DD DSN=YOUR OUTPUT FILE4,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//SYSIN    DD  *
  SORT FIELDS=COPY
  OUTFIL FNAMES=(OUT1,OUT2,OUT3,OUT4),SPLIT
//*


The following JCL will split the input file into 4 different files according to the record occurance.

Code:

//STEP0100  EXEC  PGM=SORT
//SYSOUT    DD SYSOUT=*                                   
//SORTIN    DD DSN=YOUR INPUT DSN,               
//             DISP=SHR                                   
//OUT1      DD DSN=YOUR OUTPUT FILE1,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT2      DD DSN=YOUR OUTPUT FILE2,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT3      DD DSN=YOUR OUTPUT FILE3
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT4      DD DSN=YOUR OUTPUT FILE4,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//SYSIN    DD  *
  SORT FIELDS=COPY
  OUTFIL FNAMES=OUT1,STARTREC=1,EDNREC=250
  OUTFIL FNAMES=OUT2,STARTREC=101,EDNREC=500
  OUTFIL FNAMES=OUT3,STARTREC=501,EDNREC=750
  OUTFIL FNAMES=OUT4,STARTREC=751
//*

Hope this helps...

cheers

kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
seema patni
Beginner


Joined: 04 Nov 2003
Posts: 8
Topics: 5

PostPosted: Wed Nov 05, 2003 12:45 am    Post subject: Reply with quote

Hi ,

Thanx for the kind reply .The first method works fine but i want to know that how can we split the file in the second way ( not in round robin fashion) without knowing how many records are there in that file .


Thanx
Seema
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12372
Topics: 75
Location: San Jose

PostPosted: Wed Nov 05, 2003 3:43 am    Post subject: Reply with quote

seema,

The above suggested method works even if we don't the know the no: of records in the file.The first 3 files will have 250 records each(assuming that your inout file has more than 750). The last file will have rest of the records.

please clarify us the following questions.

1. How many files do you need the input file split up?

2. How many records do you want in each file?

3. what is the LRECL & RECFM

If you want dynamic split it can be done but I need clear requirements.

Kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
seema patni
Beginner


Joined: 04 Nov 2003
Posts: 8
Topics: 5

PostPosted: Wed Nov 05, 2003 5:48 am    Post subject: Reply with quote

Hi,

I wanted to split the file equally, but i will not be knowing how many records the input file can contain.

To begin with, I wanted to know how a file could be split into 4 files. If number split could be decided dynamically, it will add value to my design. The Lrecl is 80 and record format is FB.

Again, thanks a lot for you kind reply.

Seema.
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12372
Topics: 75
Location: San Jose

PostPosted: Wed Nov 05, 2003 6:48 am    Post subject: Reply with quote

seema,

The equal splitting of the files will not always be true. If the total no of records is a multiple of the number of files to be split then you will have equal no: of records in all the files. But if it is not then the last file will have more records.

The following DFSORT/ICETOOL JCl will give you the desired results. This Job uses the horizontal math fucntions which are available in the new PTF UQ90053. If you have syncsort at your shop then change the pgm name to Synctool.

I assumed that you want to split the input file into 4 output files. This solution also assumes that you have a min of 4 records in the input file.

A brief explanation of the Job.We first take the input file and add a seqnum to it and sort on it descending. By doing so you will get last record at the beginning of the file. Now we take this value and do our manipulation to create dynamic control cards with startrec and endrec values.

Code:

//STEP0100 EXEC PGM=ICETOOL           
//TOOLMSG   DD SYSOUT=*               
//DFSMSG    DD SYSOUT=*               
//IN        DD DSN=YOUR INPUT FILE,
//             DISP=SHR
//OUT1      DD DSN=YOUR OUTPUT FILE1,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT2      DD DSN=YOUR OUTPUT FILE2,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT3      DD DSN=YOUR OUTPUT FILE3,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT4      DD DSN=YOUR OUTPUT FILE4,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//TOOLIN   DD *
  SORT FROM(IN) USING(CTL1)
  COPY FROM(IN) USING(CTL2)
//CTL1CNTL DD  *                                             
  INREC FIELDS=(SEQNUM,8,ZD)                                   
  SORT FIELDS=(1,8,ZD,D)                                       
  OUTREC FIELDS=(1,8,ZD,DIV,+4,EDIT=(TTTTTTTT))               
  OUTFIL FNAMES=CTL2CNTL,ENDREC=1,                             
  OUTREC=(C' OUTFIL FNAMES=OUT1,STARTREC=1,ENDREC=',1,8,80:X,/,
          C' OUTFIL FNAMES=OUT2,STARTREC=',                   
             +1,ADD,1,8,ZD,EDIT=(TTTTTTTT),                   
          C',ENDREC=',+2,MUL,1,8,ZD,EDIT=(TTTTTTTT),/,       
          C' OUTFIL FNAMES=OUT3,STARTREC=',                   
            +1,ADD,(+2,MUL,1,8,ZD),EDIT=(TTTTTTTT),           
          C',ENDREC=',+3,MUL,1,8,ZD,EDIT=(TTTTTTTT),/,       
          C' OUTFIL FNAMES=OUT4,STARTREC=',                   
            +1,ADD,(+3,MUL,1,8,ZD),EDIT=(TTTTTTTT))           
//CTL2CNTL  DD DSN=&T1,DISP=(,CATLG),SPACE=(TRK,(1,1),RLSE) 
//*


The output from the first sort will be as follows:

Code:

OUTFIL FNAMES=OUT1,STARTREC=1,ENDREC=00000003         
OUTFIL FNAMES=OUT2,STARTREC=00000004,ENDREC=00000006   
OUTFIL FNAMES=OUT3,STARTREC=00000007,ENDREC=00000009   
OUTFIL FNAMES=OUT4,STARTREC=00000010                   


Hope this helps...

cheers

kolusu


Last edited by kolusu on Wed Nov 05, 2003 11:50 am; edited 2 times in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Frank Yaeger
Sort Forum Moderator
Sort Forum Moderator


Joined: 02 Dec 2002
Posts: 1618
Topics: 31
Location: San Jose

PostPosted: Wed Nov 05, 2003 10:36 am    Post subject: Reply with quote

Kolusu,

You forgot the TOOLIN statements. Also, you can use SAVE for the last OUTFIL statement instead of generating STARTREC for it.

For a large file, it might be more efficient to get the count in one COPY operator and generate the control statements from that count in a second COPY operator, rather than doing both in a SORT operator. The COPY would be more efficient than the SORT.
_________________
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
Back to top
View user's profile Send private message Send e-mail Visit poster's website
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12372
Topics: 75
Location: San Jose

PostPosted: Wed Nov 05, 2003 11:06 am    Post subject: Reply with quote

Frank,

Thanks for catching error. I am editing the post to show the toolin statements. A copy operator would be more efficient if we are dealing with a large file, but will need an extra pass to format the count from the trailer.

I was under the impression that SAVE can be used along with INCLUDE/OMIT conditions. Using it along with startrec/endrec might not give the desired results.

Kolusu

PS: I will post the solution using copy operator later.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12372
Topics: 75
Location: San Jose

PostPosted: Wed Nov 05, 2003 11:46 am    Post subject: Reply with quote

Seema,

Here is another version which will give you desired results.

Code:

//STEP0100 EXEC PGM=ICETOOL           
//TOOLMSG   DD SYSOUT=*               
//DFSMSG    DD SYSOUT=*               
//IN        DD DSN=YOUR INPUT FILE,
//             DISP=SHR
//T1        DD DSN=&T1,DISP=(,PASS),SPACE=(TRK,(1,1),RLSE)
//OUT1      DD DSN=YOUR OUTPUT FILE1,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT2      DD DSN=YOUR OUTPUT FILE2,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT3      DD DSN=YOUR OUTPUT FILE3,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//OUT4      DD DSN=YOUR OUTPUT FILE4,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(CYL,(X,Y),RLSE)
//TOOLIN   DD  *           
  COPY FROM(IN) USING(CTL1) 
  COPY FROM(T1) USING(CTL2) 
  COPY FROM(IN) USING(CTL3) 
//CTL1CNTL DD  *                                               
   OUTFIL FNAMES=T1,NODETAIL,REMOVECC,TRAILER1=(COUNT)         
//CTL2CNTL DD  *                                               
  INREC FIELDS=(1,8,FS,ZD,LENGTH=8)                             
  OUTREC FIELDS=(1,8,ZD,DIV,+4,EDIT=(TTTTTTTT))                 
  OUTFIL FNAMES=CTL3CNTL,ENDREC=1,                             
  OUTREC=(C' OUTFIL FNAMES=OUT1,STARTREC=1,ENDREC=',1,8,80:X,/,
          C' OUTFIL FNAMES=OUT2,STARTREC=',                     
             +1,ADD,1,8,ZD,EDIT=(TTTTTTTT),                     
          C',ENDREC=',+2,MUL,1,8,ZD,EDIT=(TTTTTTTT),/,         
          C' OUTFIL FNAMES=OUT3,STARTREC=',                     
           +1,ADD,(+2,MUL,1,8,ZD),EDIT=(TTTTTTTT),             
          C',ENDREC=',+3,MUL,1,8,ZD,EDIT=(TTTTTTTT),/,         
          C' OUTFIL FNAMES=OUT4,STARTREC=',                     
            +1,ADD,(+3,MUL,1,8,ZD),EDIT=(TTTTTTTT))             
//CTL3CNTL  DD DSN=&T1,DISP=(,CATLG),SPACE=(TRK,(1,1),RLSE)   
//*



If you are using syncsort and you get an error on REMOVECC parameter then you are having an old version of syncsort. In that case use the following control cards.

Code:

//CTL1CNTL DD  *                                                     
   OUTFIL FNAMES=T1,NODETAIL,TRAILER1=(COUNT)                         
//CTL2CNTL DD  *                                                     
  INREC FIELDS=(2,8,FS,ZD,LENGTH=8)                                   
  OUTREC FIELDS=(1,8,ZD,DIV,+4,EDIT=(TTTTTTTT))                       
  OUTFIL FNAMES=CTL3CNTL,ENDREC=1,                                   
  OUTREC=(C' OUTFIL FNAMES=OUT1,STARTREC=1,ENDREC=',1,8,80:X,/,       
          C' OUTFIL FNAMES=OUT2,STARTREC=',                           
             +1,ADD,1,8,ZD,EDIT=(TTTTTTTT),                           
          C',ENDREC=',+2,MUL,1,8,ZD,EDIT=(TTTTTTTT),/,               
          C' OUTFIL FNAMES=OUT3,STARTREC=',                           
            +1,ADD,(+2,MUL,1,8,ZD),EDIT=(TTTTTTTT),                   
          C',ENDREC=',+3,MUL,1,8,ZD,EDIT=(TTTTTTTT),/,               
          C' OUTFIL FNAMES=OUT4,STARTREC=',                           
            +1,ADD,(+3,MUL,1,8,ZD),EDIT=(TTTTTTTT))                   
//CTL3CNTL  DD DSN=&T1,DISP=(,CATLG),SPACE=(TRK,(1,1),RLSE),RECFM=FB


Pay attention to the RECFM parameter on the CTL3CNTL file allocation. You MUST code the recfm as the report feature will create a FBA dataset.


Hope this helps...

cheers

kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Frank Yaeger
Sort Forum Moderator
Sort Forum Moderator


Joined: 02 Dec 2002
Posts: 1618
Topics: 31
Location: San Jose

PostPosted: Wed Nov 05, 2003 11:49 am    Post subject: Reply with quote

Kolusu,

{Added after I saw your post with the second job}:
I wrote this post before you posted your second job which looks a lot like mine. I'm referring to your first job here:

DFSORT can use SAVE with STARTREC and ENDREC. Any records not included by the STARTREC and ENDREC parameters of the other OUTFIL statements will be included for the OUTFIL statement with SAVE.

You only have a SORT operator in your TOOLIN. That will generate the statements in CTL2CNTL, but you need a COPY operator to use the CTL2CNTL statements. You should have:

Code:

//TOOLIN DD *
  SORT FROM(IN) USING(CTL1)
  COPY FROM(IN) USING(CTL2)
/*


So you will be sorting all of the records to get the count and generate the statements, and copying all of the records to split the file.

Here's a DFSORT/ICETOOL job for the method I suggest instead:

Code:

//FLY1 EXEC PGM=ICETOOL
//TOOLMSG   DD SYSOUT=*
//DFSMSG    DD SYSOUT=*
//IN        DD DSN=...   input file
//CT        DD DSN=&&CT,UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(,PASS)
//OUT1 DD DSN=...        output file1
//OUT2 DD DSN=...        output file2
//OUT3 DD DSN=...        output file3
//OUT4 DD DSN=...        output file4
//TOOLIN   DD *
  COPY FROM(IN) USING(CTL0)
  COPY FROM(CT) USING(CTL1)
  COPY FROM(IN) USING(CTL2)
/*
//CTL0CNTL DD  *
  OUTFIL FNAMES=CT,NODETAIL,REMOVECC,
    TRAILER1=(COUNT=(M11,LENGTH=8))
/*
//CTL1CNTL DD  *
  OUTREC FIELDS=(1,8,ZD,DIV,+4,EDIT=(TTTTTTTT))
  OUTFIL FNAMES=CTL2CNTL,ENDREC=1,
  OUTREC=(C' OUTFIL FNAMES=OUT1,STARTREC=1,ENDREC=',1,8,80:X,/,
          C' OUTFIL FNAMES=OUT2,STARTREC=',
             +1,ADD,1,8,ZD,EDIT=(TTTTTTTT),
          C',ENDREC=',+2,MUL,1,8,ZD,EDIT=(TTTTTTTT),/,
          C' OUTFIL FNAMES=OUT3,STARTREC=',
            +1,ADD,(+2,MUL,1,8,ZD),EDIT=(TTTTTTTT),
          C',ENDREC=',+3,MUL,1,8,ZD,EDIT=(TTTTTTTT),/,
          C' OUTFIL FNAMES=OUT4,SAVE')
/*
//CTL2CTNL  DD DSN=&&X1,UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(,PASS)



I copy all of the records to generate the count record, copy that one record to generate the control statements, and copy all of the records to split the file. Thus, you're doing a sort of all the records and a copy of all of the records, whereas I'm doing a copy of all the records, a copy of one record, and a copy of all the records. The two copies of all the records is faster than the sort and copy of all the records.

I ran our two jobs using 500001 records. Mine ran in less than half the CPU time of yours.
_________________
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
Back to top
View user's profile Send private message Send e-mail Visit poster's website
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12372
Topics: 75
Location: San Jose

PostPosted: Wed Nov 05, 2003 11:56 am    Post subject: Reply with quote

Frank,

Unfortunately Syncosrt does not allow edit masking on trailer record. It is 8 byte field with leading zeroes supressed. So I had to an extra inrec statement to mask the count from FS to ZD field.

Thanks for running the 2 jobs and posting the results.


Kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Job Control Language(JCL) All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
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


MVSFORUMS
Powered by phpBB © 2001, 2005 phpBB Group