Addstera

Showing posts sorted by relevance for query sort. Sort by date Show all posts
Showing posts sorted by relevance for query sort. Sort by date Show all posts

Tuesday, July 2, 2013

JCL - Some important SORT Functions.

This page will cover the very basics in SORT.  If u are not a newbie in  sort, then check this page to get some typical sort example. Sort Examples
Feel free to add your sort experience also! 

IBM DFSORT  has three Data processing functions.
a) Sort Data   b) Merges Data    c) Copies data

Basic Format of DFSORT is shown below.
SORT FIELDS = (Position-of-field, Length-of-field,Data Format,Sequence-to-be-sorted).

example:
SORT FIELDS=(2,5,CH,A)      /*A=Ascending,  D= Descending*/
Sort Fields may also look like:
SORT FILEDS = (21,5,A,5,2,A), FORMAT=CH
It implies that sorting is done on the major field which is coded first (21,5,A) and then the Secondary or Minor field (5,2,A). Character format for both being 'CH'


Character Formats used in SORT
FORMAT : Description
CH: Is used for for textual character string
ZD: Is used for Numeric Data
BI: Is used when Numeric data is stored in pure binary format
FL: Is used to store Floating Point numbers which are COMP1 and COMP2 format.
PD: Is used for packed decimal or COMP-3
CSL:Is used when Sign is stored as separate extra character and distinguished from
numeric data.


Mandatory SORT JCL Statement
//STEPNAME EXEC PGM = SORT      /* The Sort Module
//SORTIN DD                                         /*Records to be Sorted.Input dataset goes here
//SORTOUT DD                                     /* Sorted Rcords
//SYSIN DD                                           /* Sort Control Statements
//SYSOUT DD                                       /*Output Messages
//SORTLIB DD                                      /* Library for Sort/Merge Modules.Optional parameter
//SORTWKnn DD                                  /* Work data sets. Optional parameter. Required if we use
Sample JCL
//STEP02   EXEC PGM=SYNCSORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORTIN,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUT,
//            DISP=(NEW,CATLG,DELETE),UNIT=DISK,
//            DCB=(RECFM=FB,LRECL=400,BLKSIZE=8800),
//            SPACE=(TRK,(350,200),RLSE)

                     Application of Few SORT JCLS:                              

1) Copy First few Record 

//STEP02   EXEC PGM=SYNCSORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORTIN.DATASET,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUT,
//            DISP=(NEW,CATLG,DELETE),SPACE=(CYL,(200,500),RLSE),
//            DCB=(*.SORTIN),UNIT=DISK
//SYSIN    DD *
SORT FIELDS=COPY,
STOPAFT=200
/*
2) SORT DUPLICATES using SYNCSORT
//STEP02   EXEC PGM=SYNCSORT

//SYSOUT   DD SYSOUT=*

//SORTIN    DD DSN=TEST.SORTIN.DATASET,DISP=SHR

//SORTOUT  DD DSN=TEST.SORT.OUTPUT,
//            DISP=(NEW,CATLG,DELETE),UNIT=DISK,
//            DCB=(RECFM=FB,LRECL=400,BLKSIZE=8800),
//            SPACE=(TRK,(350,200),RLSE)
//SORTXSUM DD DSN=TEST.SORT.OUTPUT.DUPL,
//            DISP=(NEW,CATLG,DELETE),UNIT=DISK,
//            DCB=(RECFM=FB,LRECL=400,BLKSIZE=8800),
//            SPACE=(TRK,(350,200),RLSE)
//SYSIN    DD *
SORT FIELDS=(1,3,CH,A)
SUM FIELDS=NONE,XSUM
/*
SORTOUT will contain unique records.
SORTXSUM Will contain all the eliminated duplicates

3) Skip First 150 records and copy next 20
//STEP02   EXEC PGM=SYNCSORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORTIN.DATASET,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUT,
//            DISP=(NEW,CATLG,DELETE),SPACE=(CYL,(200,500),RLSE),
//            DCB=(*.SORTIN),UNIT=DISK
//SYSIN    DD *
SORT FIELDS=COPY,
SKIPREC = 150,
STOPAFT=20
/* 
Skip the first 150 records. Then Copy 20 records and stop.
4) COPY BASED ON CONDITION(INCLUDE CONDITION IN SORT)
//STEP02   EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORT.INPUT,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUT,
//            DISP=(NEW,CATLG,DELETE),UNIT=DISK,
//            DCB=(RECFM=FB,LRECL=400,BLKSIZE=8800),
//            SPACE=(TRK,(350,200),RLSE)
//SYSIN    DD *
     SORT FIELDS=COPY
      INCLUDE COND=(1,5,CH,EQ,C'INDIA')
/*

Check for multiple condition
//SYSIN    DD *
     SORT FIELDS=COPY
      INCLUDE COND=((1,5,CH,EQ,C'INDIA'),AND,(10,5,CH,EQ,C'1500'))
/* 


MULTIPLE INCLUDE  CONDITIONS IN SYNCSORT USING  OUTFIL FILES=01,OUTFIL FILES=02 and so on

When we are using SYNCSORT, the syntax will be different like below. We dont use COND in the include statement.Use only INCLUDE in SYNCSORT.

 SORT FIELDS=COPY                                               
 OUTFIL FILES=01,                                               
 INCLUDE=((80,1,CH,EQ,C'A'),AND,(259,5,CH,EQ,C'00077'))         
                                                                
 OUTFIL FILES=02,                                               
 INCLUDE=((259,5,CH,EQ,C'00061'),AND,                           
         ((80,1,CH,EQ,C'A'),OR,(80,1,CH,EQ,C'T')),AND,          
         (228,8,CH,GE,C'20090401'),AND,(228,8,CH,LE,C'20140401'))

                                                                


5) OMIT CONDITIONS IN SYNCSORT
//STEP02   EXEC PGM=SYNCSORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORT.INPUT,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUT,
//            DISP=(NEW,CATLG,DELETE),UNIT=DISK,
//            DCB=(RECFM=FB,LRECL=400,BLKSIZE=8800),
//            SPACE=(TRK,(350,200),RLSE)
//SYSIN    DD *
      SORT FIELDS=COPY
      OMIT COND=(10,4,CH,EQ,C'JACK')
/*
Or like
 SORT FIELDS=COPY
      OMIT COND=(10,4,CH,EQ,C'1500')

Characters which match the condition given (exmple: C'1500') will be skipped in the output file.
Multiple conditions:
SORT FIELDS=COPY                                       
OMIT COND=((34,2,CH,EQ,C'AB'),AND,(74,1,CH,EQ,C' '))

Wednesday, July 24, 2013

Some more SYNCSORT/DFSORT Examples with JCL

Earlier we have seen the basic Sort example to start of with. Here lets cover some more typical   SORT examples

ALTSEQ in SYNCSORT/DFSORT
//**************************************************
//STEP02   EXEC PGM=SYNCSORT
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORT.INPUT,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUT,
//            DISP=(NEW,CATLG,DELETE),UNIT=DISK,
//            DCB=(RECFM=FB,LRECL=400,BLKSIZE=8800),
//            SPACE=(TRK,(350,200),RLSE)
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
      SORT FIELDS=COPY
       ALTSEQ CODE=(E340,C940,4D40,5D40)
       OUTREC FIELDS=(1,80,TRAN=ALTSEQ)
/*
EXPLANATION:

ALTSEQ will replace the character in the INPUT File with that specified.Here in ALTSEQ code we are specifying 
ALTSEQ CODE=(E340,C940,F540,5D40).
'E3' is the hexadecimal value for alphabet 'I'.
'40' is the hex equivalent for SPACE. 
So ALTSEQ CODE=E340 will replace 'I' with 'SPACE'. 
Like wise we can do for any characters provided we know the HEX equivalent of that character.
Similarly '4D40' will replace '5' with 'SPACE'. So in OUTPUT we will see 'I' and '5' getting replaced by SPACE.

INPUT:
**************
INDIA    MIKA
INDIA    1500
SWEDEN   2500
SPAIN    1096
TURKEY   2000
BRAZIL   6700
HOLLAND  3456
NEPAL    1209
OUTPUT:













SYNCSORT TO GET COUNT OF RECORDS
//STEP02   EXEC PGM=SYNCSORT
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORT.INPUT,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUNT,
//            DISP=(NEW,CATLG,DELETE),UNIT=DISK,
//            SPACE=(TRK,(350,200),RLSE)
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
      SORT FIELDS=(1,3,CH,A)
      OUTFIL REMOVECC,NODETAIL,
      TRAILER1=('NO OF RECORDS:',COUNT=(M11,LENGTH=8))
/*
REMOVECC omits the ANSI carriage control character from all of the report records.
NODETAIL generates a report with no data records.
SYNCSORT TO PRINT A LINE AFTER EVERY  RECORDS
//STEP02   EXEC PGM=SYNCSORT
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORT.INPUT2,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUNT,
//            DISP=(NEW,CATLG,DELETE),UNIT=SYSDA,
//            SPACE=(TRK,(350,200),RLSE)
//*ORTOF02 DD DUMMY
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
      SORT FIELDS=COPY
      OUTFIL BUILD=(1,80,/,80C'-')

/*
SYNCSORT TO EXTRACT A RECORD USING SUB STRING CONDITION.
//STEP02   EXEC PGM=SYNCSORT
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORT.INPUT2,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUNT,
//            DISP=(NEW,CATLG,DELETE),UNIT=SYSDA,
//            SPACE=(TRK,(350,200),RLSE)
//*ORTOF02 DD DUMMY
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
      INCLUDE COND=(1,20,SS,EQ,C'IS')
      SORT FIELDS=COPY
/*
SS looks for the sub string 'IS' in the position 1 to 20 in the input file and puts that reocrd in the output. 


SYNCSORT TO CONVERT PACKED DECIMAL TO ZONNED DECIMAL
//STEP02   EXEC PGM=SYNCSORT
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTIN   DD DSN=TEST.SORT.INPUT2,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUTPUNT,
//            DISP=(NEW,CATLG,DELETE),UNIT=SYSDA,
//            SPACE=(TRK,(350,200),RLSE)
//*ORTOF02 DD DUMMY 
//SYSOUT   DD SYSOUT=*
//SYSIN    DD * 
      SORT FIELDS=COPY
      OUTREC FIELDS=(1,5,PD,ZD) 
/*
input:
----+
*****
1223A
23434
*****
Output:
----+----1
**********
.1.2.2.3.
.2.3.4.3
**********
JOINKEYS  for SYNCSORT
Use sort to filter out matched and unmatched record
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTJNF1 DD DSN=TEST.SORT.INPUT2,DISP=SHR
//SORTJNF2 DD DSN=TEST.SORT.INPUT3,DISP=SHR
//SORTOF01 DD DSN=TEST.SORT.OUTPUNT,
//            DISP=(NEW,CATLG,DELETE),UNIT=SYSDA,
//            DCB=(*.SORTJNF1),
//            SPACE=(TRK,(350,200),RLSE)
//SORTOUT  DD DUMMY
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
      JOINKEYS FILES=F1,FIELDS=(1,5,A)
      JOINKEYS FILES=F2,FIELDS=(1,5,A)
      JOIN UNPAIRED,F1,ONLY
      REFORMAT FIELDS=(F1:1,5)
      SORT FIELDS=COPY
      OUTFIL FILES=01,BUILD=(1,5) 
/
EXPLANATION:The above JCL will filter out the unmatched record from INPUT2 by comparing with INPUT3. 
To find out the matching record we need to use.
//SYSIN    DD *
      JOINKEYS FILES=F1,FIELDS=(1,5,A)
      JOINKEYS FILES=F2,FIELDS=(1,5,A)
      REFORMAT FIELDS=(F1:1,5)
      SORT FIELDS=COPY
      OUTFIL FILES=01,BUILD=(1,5)
/*
DFSORT  TO WRITE HEADER ,TRAILER RECORDS
SYSIN DD*
OPTIONS COPY

OUTFIL REMOVECC,
TRAILER1=('TOTAL:',TOT=(10,6,ZD))
Adding the length and mask sub parameter:
SORT FIELDS=COPY                             
OUTFIL REMOVECC,NODETAIL,                    
TRAILER1=('TOTAL:',TOT=(10,6,ZD,M1,LENGTH=9))
 


To Write more than one Trailer we need to use the keywords "Trailer1,Trailer2,Trailer3."
we will see how to write trailer for count of records and total of records.

OPTION COPY                                                   
OUTFIL REMOVECC,                                               TRAILER1=('TOTAL:',TOT=(10,6,ZD,LENGTH=10,EDIT=(TTTTTTTTTT))),
TRAILER2=('COUNT:',COUNT=(LENGTH=10))
 
                     
 


Explanation of the keywords used: TRAILER1,TRAILER2,TRAILER3,COUNT,TOT are the keywords for SORT cards.OUTFIL is used to print the reports.REMOVECC in sort is used to remove the Cariage control inserted by DFSORT in first position.
The value of '1' in the first position of a record tells the printer to start a new page.To remove these carriage control, we need to use REMOVECC in OUTFIL statement.

TOT=(10,6,ZD) will make the total on 6 digits starting in 10th column.
If we use NODETAIL,then we would see only the trailer and header records.Other records would not be shown in output.
Omitting NODETAIL in OUTFIL would ensure we see all records along with trailer and header.


Output:
----+----1----+----2----+----3-- 
******************************** 
HARLEY   123456MEXICO            
DAVID    658999CANADA            
COUNT:        2                  
TOTAL:0000782455                 
******************************** 
    


To Add Header in SORT using HEADER1 parameter :
OPTION COPY                                                   
OUTFIL REMOVECC,                                              
HEADER1=('REPORT GENERTED AS ON:',&DATE,//,22C'-'),           
TRAILER1=('TOTAL:',TOT=(10,6,ZD,LENGTH=10,EDIT=(TTTTTTTTTT))),
TRAILER2=('COUNT:',COUNT=(LENGTH=10))
                         


Output:
*********************************
REPORT GENERTED AS ON:03/02/13   
---------------------            
HARLEY   123456MEXICO            
DAVID    658999CANADA            
COUNT:        2                  
TOTAL:0000782455                 
******************************** 


DFSORT  TO COMPARE THE HEXCODE/ASCII OF CHARACTER ALPHABETS.
//STEP02   EXEC PGM=SORT 
//SORTIN   DD DSN=TEST.SORTINC,DISP=SHR
//SORTOUT  DD DSN=TEST.SORT.OUT1,
//            DISP=(NEW,CATLG,DELETE),UNIT=(SYSDA,59),
//            DCB=*.SORTIN, 
//            SPACE=(TRK,(50,100),RLSE) 
//SYSOUT   DD SYSOUT=* 
//SYSPRINT DD SYSOUT=* 
//SYSIN    DD *
SORT FIELDS=COPY  
INCLUDE COND=(3,1,AC,GE,X'41',AND,3,1,AC,LE,X'4F')

Input:
00B0000
00A1462
00C1850
00D2108
00E2109
00FM006
00ZM007
00ZM008
00YM023
00CM050


Output:
00B0000
00A1462
00C1850
00D2108
00E2109
00FM006
00CM050

Explanation: The above sort card checks for the characters from A to O.  All other characters will be eliminated. '41' hex of 'A' and '4F' is hex of 'O' in ASCII.
DFSORT  TO INSERT/ADD  DELIMITER/CHARACTERS AFTER EVERY RECORD.

//SYSIN    DD *                             
SORT FIELDS=COPY                            
INREC BUILD=(1,60,SQZ=(SHIFT=LEFT,MID=C'~'))

Explanation:MID=C'`' tells DFSORT to insert the character between the fields.

SORT  TO REMOVE SPACES BETWEEN CHARACTERS
SQZ operator in DFSORT/SYNCSORT can be used to remove spaces between characters.
Input:Q WE R T Y 
Expected Output: QWERTY
We can use SQZ operator to remove the spaces and format the field.
OPTION COPY                           
OUTREC FIELDS=(1,40,SQZ=(SHIFT=LEFT)) 

Explanation: We are squeezing out the blanks and  shifting the characters to the left for all the data in thje positions 1 to 40.

Friday, September 26, 2014

DFSORT/SYNCSORT to include spaces, insert fixed strings and refortmat the records using OUTREC

Continuing with the Previous SORT examples, this section will have some SORT features to understand the INREC/OUTREC features and how they work.
In the following sort example, i am trying to insert spaces and insert fixed string in the input file and format the output record.
Since , we are trying to build the record, ie, manipulate the entire record structure here and there, we will go with OUTREC BUILD option. This gives us complete control over the record structure. We can pick up any record from any position and place it anywhere as per the requirement.
Here goes my input file.
----+----1----+----2----+----3----+-
********************************* To
A001MUKESHN                        
A002GRECHEN                        
A003STEVEEN                        
A003STEVEEN                        
A004STEVEEN                        
A004STEVEEN                        
******************************** Bottom
SORT JCL
//STEP0010 EXEC PGM=SORT                         
//SYSOUT    DD SYSOUT=*                          
//SORTWK01  DD UNIT=DISK,SPACE=(CYL,(100,100))   
//SORTIN    DD DSN=BHI522.SORT.TEST1,DISP=SHR    
//SORTOUT    DD DSN=BHI5122.TEST.SORT.OP3,        
//          DISP=(,CATLG),UNIT=TEST,             
//          SPACE=(CYL,(50,50),RLSE)             
//SYSIN     DD *                                 
  SORT FIELDS=COPY                               
  OUTREC BUILD=(1:1,4,5:2X,8:C'TST',13:5,7)     
//*                                               

Output:
----+----1----+----2----+----3----+----4----+----5----+--
********************************* Top of Data ***********
A001   TST  MUKESHN                                     
A002   TST  GRECHEN                                     
A003   TST  STEVEEN                                     
A003   TST  STEVEEN                                     
A004   TST  STEVEEN                                     
A004   TST  STEVEEN                                     
******************************** Bottom of Data *********

As we see here, OUTREC parameter, '1:1,4' tells sort to :Take record of length 4 bytes starting from 1st column and  place it in 1st column of the output file.
5:2X will put 2 byte of spaces.  X indicate spaces to be included. When we use 3X, that means 3 spaces to be put.
8:C'TST'   will tell sort to put the string 'TST' from 8th byte of the output record.
13:5,7 Will instruct sort to: Take the record of length 7 bytes from 5th column of the input file and put from 13th column in the output file.
Now match the output, and we can see the result!
A Point to remember : For INREC and OUTREC we can use FIELDS or BUILD. For OUTFIL , we can use  OUTREC or BUILD

2. Get the HEX Values using SORT
Using the Same input file, will use the OUTFIL OUTREC command to print the hex values
   ............... same as above JCL......
  SORT FIELDS=COPY                  
  OUTFIL OUTREC=(1:1,4,TRAN=HEX)    
//*                                
Output will look like:
----+----1--
************
C1F0F0F1   
C1F0F0F2   
C1F0F0F3   
C1F0F0F3   
C1F0F0F4   
C1F0F0F4   
************
Will keep updating ........

Saturday, September 26, 2015

Including Date field in the output file using SORT

Including Date field in the output file:

Many a times it is required to include the date in the output file. This can be done using DATE parameter in SORT.
There are 3 DATE parameter option available, DATEn, DATEn(c) and DATEnP where n=1, 2 or 3.

Consider the input file INFILE,
1111111111111111111111111111
1111111111111111111111111111
1211111111111111111111111111
1311111111111111111111111111
1411111111111111111111111111
1511111111111111111111111111
1611111111111111111111111111
1711111111111111111111111111
1811111111111111111111111111
1911111111111111111111111111
2011111111111111111111111111
2111111111111111111111111111
The output date is in Zoned Decimal format.
The DATE1 occupies 10 bytes and gives the date in YYYYMMDD format.
The DATE2 occupies 6 bytes and gives the date in YYYYMM format.
The DATE3 occupies 7 bytes and gives year and Julian date (JDT) as YYYYJDT format.
The JCL’s below show the use of DATEn parameter. The current date August 26, 2010(Julian Date 238)
//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INFILE,DISP=SHR
//SORTOUT DD DSN=OUTFILE1,DISP=SHR
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(1,29,&DATE1)
//

The contents of OUTFILE are as below,
OUTFILE:
1111111111111111111111111111 20100826
1111111111111111111111111111 20100826
1211111111111111111111111111 20100826
............

On using DATE1 we have the current date in YYYYMMDD format.
//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INFILE,DISP=SHR
//SORTOUT DD DSN=OUTFILE2,DISP=SHR
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(1,29,&DATE2)
//
The contents of OUTFILE2 are as below,
1111111111111111111111111111 201008
1111111111111111111111111111 201008
1211111111111111111111111111 201008
.........
On using DATE2 we have the output date in YYYYJDT format

//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INFILE,DISP=SHR
//SORTOUT DD DSN=OUTFILE2,DISP=SHR
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(1,29,&DATE3)
//
The contents of the OUTFILE2 is as below,
1111111111111111111111111111 2010238

Using the DATEn(c) parameter:
On using the DATEn(C) parameter, the output date appears in formatted way wherein a character ‘/’ is placed between the year month and date fields.
DATE1(c) occupies 10 bytes and the format is YYYY/MM/DD.
DATE2(c) occupies 7 bytes and the format is YYYY/MM.
DATE3(c) occupies 7 bytes and the format is YYYY/JDT.

Using the DATEnP parameter:
On using DATEnP the output appears in Packed decimal format. So the number of bytes occupied is lesser than DATEn parameter. Other than this there is no difference between DATEn and DATEnP.
The DATE1 occupies 5 bytes and gives the date in YYYYMMDD format.
The DATE2 occupies 4 bytes and gives the date in YYYYMM format.
The DATE3 occupies 4 bytes and gives year and Julian date (JDT) as YYYYJDT format.
1111111111111111111111111111 2010238


Retrieving Information on records having older dates:
Consider a case wherein we need to retrieve records that have yesterday’s date.
The JCL is as below,
//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INFILE1,DISP=SHR
//SORTOUT DD DSN=OUTFILE3,DISP=SHR
//SYSIN DD *
SORT FIELDS=COPY
INCLUDE COND=(30,8,CH,EQ,&DATE1-1)
OUTREC FIELDS=(1,40)
//

Thursday, September 3, 2015

Splitting Input Files using Sort. Use of SPLIT ,SPLITBY,SPLIT1R commmands

SPLIT command spits the output records one record at a time among output datasets. This happens until all the output records are written. The split happens in rotation among the datasets mentioned in the OUTFIL.
The First record from the output records is written to first dataset mentioned in the OUTFIL group, the Second record from the output records gets written to the second dataset mentioned in the OUTFIL group and so on.
When each OUTFIL dataset has 1 record, the rotation starts again with the dataset mentioned first in the OUTFIL group.
The records are not contiguous in the OUTFIL datasets.
The Below JCL splits the data in INFILE and copies to OUTFILE1 and OUTFILE2 as mentioned above.

Consider the contents of Input File - INFILE as below:

1111111111111111111111111111
1211111111111111111111111111
1311111111111111111111111111
1411111111111111111111111111
1511111111111111111111111111
1611111111111111111111111111
1711111111111111111111111111
1811111111111111111111111111
1911111111111111111111111111
2011111111111111111111111111
2111111111111111111111111111
Let us use the commands and see the outputs.

The Below JCL splits the data in INFILE and copies to OUTFILE1 and OUTFILE2 as mentioned above.
//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INFILE,DISP=SHR
//SORTOUT1 DD DSN=OUTFILE1,DISP=SHR
//SORTOUT2 DD DSN=OUTFILE2,DISP=SHR
//SYSIN DD *
SORT FIELDS=COPY
OUTFIL FNAMES=(SORTOUT1,SORTOUT2),SPLIT
/*

The contents of OUTFILE1 and OUTFILE2 would be as below,
OUTFILE1
1111111111111111111111111111
1311111111111111111111111111
1511111111111111111111111111
1711111111111111111111111111
1911111111111111111111111111
2111111111111111111111111111
OUTFILE2
1211111111111111111111111111
1411111111111111111111111111
1611111111111111111111111111
1811111111111111111111111111
2011111111111111111111111111
OUTFILE1 dataset contains records 1, 3, 5…so on.
OUTFILE2 dataset contains records 2, 4, 6…so on.
Note that the records in the output datasets are not contiguous.

SPLITBY Command:

SPLITBY splits the output records M records at a time in rotation among the datasets mentioned in the OUTFIL. This happens until all the output records are written.
The First Set of records from the output records gets written to first dataset mentioned in the OUTFIL group, the Second Set of records from the output records gets written to the second dataset mentioned in the OUTFIL group and so on.
When each OUTFIL dataset has the specified set of records, the rotation starts again with the dataset mentioned first in the OUTFIL group.
The syntax is SPLITBY=M, where M=1,2,3…so on
The records are not contiguous in the OUTFIL datasets.
SPLITBY=1 is equivalent to SPLIT.
The below JCL splits the data in INFILE and copies to OUTFILE3 and OUTFILE4 as mentioned above.
//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INFILE,DISP=SHR
//SORTOUT1 DD DSN=OUTFILE3,DISP=SHR
//SORTOUT2 DD DSN=OUTFILE4,DISP=SHR
//SYSIN DD *
SORT FIELDS=COPY
OUTFIL FNAMES=(SORTOUT1,SORTOUT2),SPLITBY=3
/*
The contents of OUTFILE3 and OUTFILE4 would be as below,
OUTFILE3
1111111111111111111111111111
1211111111111111111111111111
1311111111111111111111111111
1711111111111111111111111111
1811111111111111111111111111
1911111111111111111111111111
OUTFILE4
1411111111111111111111111111
1511111111111111111111111111
1611111111111111111111111111
2011111111111111111111111111
2111111111111111111111111111
OUTFILE3 contains records (1, 2, 3), (7, 8, 9).
OUTFILE4 contains records (4, 5, 6), (10, 11).
Note that the records in the output datasets are not contiguous.

SPLIT1R splits output records M records at a time in one rotation among the datasets mentioned in the OUTFIL. This happens until all the records are written. In SPLIT1R the rotation happens only once among the OUTFIL datasets.
If on reaching the last OUTFIL, more than M records from the output records is left, all of those would be move to last OUTFIL.
If the input has only M records, then all input records will get moved to the first OUTFIL. The remaining OUTFIL datasets will be empty.
The syntax is SPLIT1R=M, where M=1, 2, 3…so on.
The records are contiguous among the OUTFIL datasets.
The below JCL’s splits the data in INFILE,
JCL1:
//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INFILE,DISP=SHR
//SORTOUT1 DD DSN=OUTFILE5,DISP=SHR
//SORTOUT2 DD DSN=OUTFILE6,DISP=SHR
//SYSIN DD *
SORT FIELDS=COPY
OUTFIL FNAMES=(SORTOUT1,SORTOUT2),SPLIT1R=5

The output files contents are shown below,
OUTFILE5:
1111111111111111111111111111
1211111111111111111111111111
1311111111111111111111111111
1411111111111111111111111111
1511111111111111111111111111
OUTFILE6:
1611111111111111111111111111
1711111111111111111111111111
1811111111111111111111111111
1911111111111111111111111111
2011111111111111111111111111
2111111111111111111111111111
There are two output files, and M=5. The input INFILE contains 11 records.
The OUTFILE5 contains records 1, 2, 3, 4, 5.
The dataset OUTFILE6 contains records 6, 7, 8, 9, 10, 11(i. e all the remaining records)

JCL2:

//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INFILE,DISP=SHR
//SORTOUT1 DD DSN=OUTFILE7,DISP=SHR
//SORTOUT2 DD DSN=OUTFILE8,DISP=SHR
//SYSIN DD *
SORT FIELDS=COPY
OUTFIL FNAMES=(SORTOUT1,SORTOUT2),SPLIT1R=11
//
The output file contents are shown below:

OUTFILE7:
1111111111111111111111111111
1211111111111111111111111111
1311111111111111111111111111
1411111111111111111111111111
1511111111111111111111111111
1611111111111111111111111111
1711111111111111111111111111
1811111111111111111111111111
1911111111111111111111111111
2011111111111111111111111111
2111111111111111111111111111

OUTFILE8
empty as expected.