Mainframes 360
The one stop destination for System Z professionals

Monday, August 3, 2009

DFSORT – OUTREC FIELDS Control Statement, Performing Arithmetic on Numeric Fields, OUTREC OVERLAY and OUTREC IFTHEN Control Cards


Q. In the previous tutorial, you’ve told me how to obtain the Sum(Aggregation) of records using SUM FIELDS. Some of the fields in the Output Report are not meaningful. How do I display only the relevant fields, and remove the unnecessary ones?
Consider the following Input Dataset -

----+----1----+----2----+----3----+----4----+----5----+----6----+
AG10001  RAMESH CHANDRA GUHA INDIA     MAHARASHT MUMBAI    01000
AG10002  QUASAR SHABBIR CHUN INDIA     MAHARASHT PUNE      02000
AG10003  VEERAMANI DARYAGANJ INDIA     MAHARASHT NAGPUR    03000
AG10004  DELPHAN FERANDAZ    INDIA     TAMIL NAD CHENNAI   04000
AG10005  PADMAVATHI SUNDARAM INDIA     TAMIL NAD SALEM     05000
AG10006  NEELESHWARI IYER    INDIA     TAMIL NAD ERNAKULAM 06000
AG10007  AJAY NANUBHAI PARSA INDIA     WEST BENG KOLKATA   07000
AG10008  MEHUL POPATLAL SUTA INDIA     WEST BENG KHARAGPUR 08000
AG10009  KRITHIKA RAMANUJAM  INDIA     WEST BENG SUNDARBAN 09000
AG10010  ANKUR CHOUDHARY     INDIA     PUNJAB    AMRITSAR  10000
AG10011  HIREN NITIN SHETH   INDIA     PUNJAB    JALANDHAR 11000
AG10012  DARSHAN SHAH        INDIA     HARYANA   CHANDIGAR 12000


For finding the Total Sales Figure of all Insurance Agents(01000+02000+...+12000), we must use the SUM FIELDS Control Statement of DFSORT Tool. If we apply the SUM FIELDS control statement, on DFSORT as :

SUM FIELDS=(60,5,ZD)                                                 

We get the following Output Dataset :

----+----1----+----2----+----3----+----4----+----5----+----6----+
AG10001  RAMESH CHANDRA GUHA INDIA     MAHARASHT MUMBAI    78000


This tells us that the Total Sales of all Insurance Agents in COUNTRY=INDIA is 78,000. All other fields are irrelevant/not-meaningful. Now, let’s say I wanted to display only the COUNTRY and TOTAL SALES Field in the Output Report.

So, I’ve written the following JCL/JOB Stream -

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
//CAA0176A JOB A123,QUASAR,CLASS=G,MSGCLASS=Y,NOTIFY=&SYSUID           
//STEP01 EXEC  PGM=SORT,REGION=1024K                                   
//SORTIN DD    DSN=CAA0176.DEMO.SORTIN,DISP=SHR                        
//SYSPRINT DD  SYSOUT=*                                                
//SYSOUT DD    SYSOUT=*                                                
//SORTXSUM DD  DSN=CAA0176.DEMO.REPORT,DISP=SHR                        
//SORTOUT DD   DSN=CAA0176.DEMO.SORTOUT,DISP=SHR                       
//SYSIN  DD    *                                                       
  SORT FIELDS=(30,10,CH,A)                                             
  SUM FIELDS=(60,5,ZD)                                                 
  OUTREC FIELDS=(30,5,2X,60,5)                                         
//                   
                                                 


The OUTREC FIELDS Control Statement is used to display only select fields in the Output Report, and eliminate the unnecessary/irrelevant ones.
In the Input Dataset,
COUNTRY Field = Starts at Position 30 and has length 5.
SALES   Field = Starts at Position 60 and has length 5.
We would like only these 2 fields to be displayed in the Final Output File. Hence, we must code the OUTREC FIELDS Control Statement as
OUTREC FIELDS=(column1,column2,...)

OUTREC FIELDS=(30,5,2X,60,5)

Here, 2X inserts 2 whitespaces(blanks) between COUNTRY and SALES Field. The Output File Dataset is as follows :

----+----1----+
INDIA  78000  

Q. Hey, I wanted the records in the above Output report to be displayed in Hexadecimal format – the EBCDIC values in Hex, just like how its really stored in a Computer? How do I do it in JCL?

Well, you just need to use the HEX Switch in the OUTREC FIELDS Control Statement. So, in the OUTREC FIELDS Control Statement for the above output report, add the HEX Switch to all fields, you want to be displayed in HEX -

OUTREC FIELDS=(30,5,HEX,2X,60,5,HEX)

The above OUTREC FIELDS Control Statement, when submitted as a part of the Job Stream, gives the following Output Report:

----+----1----+----2----+
C9D5C4C9C1  F7F8F0F0F0  

Q. Hey I have had enough of Sum/Aggregation! Gimme a break.. Show me something else. Like how do I perform some Arithmetic Operations on the numeric field of the Input Records?

Let me just flash before you the Input Dataset, that I’ve chosen for this example. This is the data as of the year 2008.

----+----1----+----2----+----3----+----4----+----5----+----6----+
AG10001  RAMESH CHANDRA GUHA INDIA     MAHARASHT MUMBAI    01000
AG10002  QUASAR SHABBIR CHUN INDIA     MAHARASHT PUNE      02000
AG10003  VEERAMANI DARYAGANJ INDIA     MAHARASHT NAGPUR    03000
AG10004  DELPHAN FERANDAZ    INDIA     TAMIL NAD CHENNAI   04000
AG10005  PADMAVATHI SUNDARAM INDIA     TAMIL NAD SALEM     05000
AG10006  NEELESHWARI IYER    INDIA     TAMIL NAD ERNAKULAM 06000
AG10007  AJAY NANUBHAI PARSA INDIA     WEST BENG KOLKATA   07000
AG10008  MEHUL POPATLAL SUTA INDIA     WEST BENG KHARAGPUR 08000
AG10009  KRITHIKA RAMANUJAM  INDIA     WEST BENG SUNDARBAN 09000
AG10010  ANKUR CHOUDHARY     INDIA     PUNJAB    AMRITSAR  10000
AG10011  HIREN NITIN SHETH   INDIA     PUNJAB    JALANDHAR 11000
AG10012  DARSHAN SHAH        INDIA     HARYANA   CHANDIGAR 12000


In the year 2009, due to a performance bonus given to Insurance Agents, they all put in more efforts and in the next quarter it was observed, that their Sales grew by 10 percent. Write a Batch JOB/JCL that increases the Sales of Insurance Agents by 10 percent. So, you need to generate a report for Sales for the financial Year ending 2009, showing a 10% rise in the SALES Figure for all the agents.

To perform arithmetic(like increasing/addition) on numeric fields, we can use several operators like ADD,SUB,MUL,DIV,MOD inside the OUTREC FIELDS Control Statement. To treat a field as numeric, and to be able to perform numerical operations on it, we code ZD(Zoned Decimal) specifier.

To raise the Sales figure by 10 percent, we need to multiply the Sales x 1.1. But, since decimal(float) values are not allowed, we will multiply SALES x 11, and then describe the format of the resultant Edited field. The format of the Edited field can be specified using EDIT Subparameter.

If we have input sales = 1000, we multiply by 11, 1000 x 11 = 11000.
To display correct result, decimal point needs to be shifted one place left.
So, format is TTTT.T(where T stands for any significant digit to be displayed). We can add a comma like T,TTT.T. Some sales figures are above 10,000(5 digits). So, we need to ensure that they are also displayed correctly. Thus, we need to add an I(Insignificant digit).

We specify the format for the output field using EDIT Parameter. We will code the EDIT Parameter for the above example as,

EDIT=(IT,TTT.T)

This is how the Batch JOB/JCL for raising the Sales by 10 percent looks :

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
//CAA0176K JOB A123,QUASAR,CLASS=G,MSGCLASS=Y,NOTIFY=&SYSUID           
//STEP01 EXEC  PGM=SORT,REGION=1024K                                   
//SORTIN DD    DSN=CAA0176.DEMO.SORTIN,DISP=SHR                        
//SYSPRINT DD  SYSOUT=*                                                
//SYSOUT DD    SYSOUT=*                                                
//SORTXSUM DD  DSN=CAA0176.DEMO.REPORT,DISP=SHR                        
//SORTOUT DD   DSN=CAA0176.DEMO.SORTOUT,DISP=SHR                       
//SYSIN  DD    *                                                       
  SORT FIELDS=(30,5,CH,A) -                                            
  OUTREC FIELDS=(30,5,2X,(60,5,ZD,MUL,+11),EDIT=(IT,TTT.T),80:X)        
//                                                                     


Upon submitting the above Job Stream, the final Output Report for the Sales 2009, which shows a 10% increase in Sales of Each Insurance Agent, looks something like this -

----+----1----+
INDIA   1,100.0
INDIA   2,200.0
INDIA   3,300.0
INDIA   4,400.0
INDIA   5,500.0
INDIA   6,600.0
INDIA   7,700.0
INDIA   8,800.0
INDIA   9,900.0
INDIA  11,000.0
INDIA  12,100.0
INDIA  13,200.0

Q. How do you reformat records with OUTREC OVERLAY Control Statement?

When we use OUTREC FIELDS to re-format the output records, you need to specify all the fields/items, that you desire to appear in the Output Record. You must tell the DFSORT tool through the OUTREC FIELDS Control Statement, every item that you would like the record. Thus, you have to build the re-formatted record, one item at a time - field by field. In between, you can add some special characters like comma(,) or currency symbol($). This can be very tedious and cumbersome, if the record has a large length and contains many fields/columns.

If you intend to change/modify only a handful of columns, an easier and more convenient option is to use the OVERLAY Control Statement. Note that OVERLAY statement can be used to do the same tasks that you can accomplish with OUTREC Statement.

Let me show you a simple example which illustrates how to raise the Sales figure of the Insurance Agents like in the above example, but using the OUTREC OVERLAY Statement. This example proves, how easy it is to use the OVERLAY statement as opposed to the meticulous and cumbersome OUTREC FIELDS Control Statement.

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
//CAA0176A JOB A123,QUASAR,CLASS=G,MSGCLASS=Y,PRTY=15,NOTIFY=&SYSUID 
//STEP01 EXEC  PGM=SORT,REGION=1024K                                 
//SORTIN DD    DSN=CAA0176.DEMO.SORTIN,DISP=SHR                      
//SYSPRINT DD  SYSOUT=*                                              
//SYSOUT DD    SYSOUT=*                                              
//SORTXSUM DD  DSN=CAA0176.DEMO.REPORT,DISP=SHR                      
//SORTOUT DD   DSN=CAA0176.DEMO.SORTOUT,DISP=SHR                     
//SYSIN  DD    *                                                     
  OPTION COPY -                                                      
  OUTREC OVERLAY=(60:60,5,ZD,ADD,(60,5,ZD,DIV,+10),TO=ZD,LENGTH=5)   

Q. How the OUTREC IFTHEN Control Statement work? Can you elaborate by showing a simple JCL/Job stream?

OUTREC FIELDS and OUTREC Overlay allows you to apply the same reformatting to all the Output Records. However, if you would like to apply different re-formatting to different output records, then one should use the IFTHEN option. By using the IFTHEN option, one can apply different OUTREC FIELDS or OUTREC OVERLAY(formats) statements to different output records.

Suppose, we would like the Output Report to be generated as follows -
1) If SALES of Agent < 06000, then Increase = 10%
2) If SALES of Agent >= 06000, then Increase = 20%

So, for all records having sales < 06000, we multiply(MUL) by 1.1.
For all records having sales >= 06000, we multiply(MUL) by 1.2.
Thus, we can multiply records by +11 and +12 respectively, in JCL, and display the output field using the EDIT Format, EDIT=(IT,TTT.T)

----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- 
//*--------------------------------------------------------------------
//*OUTREC IFTHEN Control Statement – Reformatting Records differently    
//*--------------------------------------------------------------------
//CAA0176Q JOB A123,QUASAR,CLASS=G,MSGCLASS=Y,PRTY=15,NOTIFY=&SYSUID   
//STEP01 EXEC  PGM=SORT,REGION=1024K                                   
//SORTIN DD    DSN=CAA0176.DEMO.SORTIN,DISP=SHR <==INPUT FILE          
//SYSPRINT DD  SYSOUT=*                                                
//SYSOUT DD    SYSOUT=*                                                
//SORTOF01 DD  DSN=CAA0176.DEMO.REPORT,DISP=(OLD,KEEP,KEEP) <==REPORT  
//SORTOUT DD   DSN=CAA0176.DEMO.SORTOUT,DISP=(OLD,KEEP,KEEP) <==OUTPUT 
//SYSIN  DD    *       <== INSTREAM CONTROL STATEMENTS                 
  OPTION COPY                                                          
  OUTREC IFTHEN=(WHEN=(60,5,ZD,LT,06000), -                            
  BUILD=(1:1,9,10:10,20,X,(60,5,ZD,MUL,+11),EDIT=(IT,TTT.T))),         
  IFTHEN=(WHEN=(60,5,ZD,GE,06000), -                                   
  BUILD=(1:1,9,10:10,20,X,(60,5,ZD,MUL,+12),EDIT=(IT,TTT.T)))


The Output Report for the above Batch Job/JCL looks as follows : AG10004

----+----1----+--
AG10001  1,100.0
AG10002  2,200.0
AG10003  3,300.0
AG10004  4,400.0
AG10005  5,500.0
AG10006  7,200.0
AG10007  8,400.0
AG10008  9,600.0
AG10009 10,800.0
AG10010 12,000.0
AG10011 13,200.0
AG10012 14,400.0

To many people who are thrown to work at a mainframe computer on their first job, they feel lost. Mainframe people seem to speak a completely different language and that doesn't make life easy. What's more, the books and manuals are incredibly hard to comprehend.

"What on earth is a Mainframe?" is an absolute beginner's guide to mainframe computers. We'll introduce you to the hardware and peripherals. We'll talk about the operating system, the software installed on a mainframe. We'll also talk about the different people who work on a mainframe. In a nutshell, we'll de-mystify the mainframe.

Readers based in India, can buy the e-book for Rs. 50 only or the print book. International readers based in the US and other countries can click here to purchase the e-book.