Saturday, October 18, 2014

Command shell (option 6) in mainframe - Executing commands through Terminal Utility program IKJEFT01

Most of us have definitely seen or used in some way or other  the command shell(option 6) from ISPF panel. This is very useful command window. TSO /E allows us to talk to MVS  either through TSO E commands , or the ISPF pannel(like option 6) as i was mentioning above. In some work , i came across a scenario where i need to execute certain commands in command shell.
For example the following  commands:
REMOVE  I1612XX GROUP(MYGROUP) OWNER(MYGROUP)               
REMOVE  I171    GROUP(MYGROUP) OWNER(MYGROUP)               
CONNECT I151    GROUP(MYGROUP) OWNER(MYGROUP) AUTHORITY(USE)
CONNECT I151    GROUP(MYGROUP) OWNER(MYGROUP) AUTHORITY(USE)
The simplest way is to to go to ISPF and go to option 6. Then execute each command manually .

But the tweek in my case was to execute these commands in  batch and collect the command logs, ie, whether these commands were executed or not and all details.

So, here is the utility IKJEFT01 which we can use. Its other name is terminal utility program.
Whatever we want to execute in the pannel screen can be executed from batch as well using ikjeft01.
So, lets have the JCL for  using this utility.
Way1
//STEP001  EXEC PGM=IKJEFT01                
//SYSTSIN  DD   DSN=Your-Dataset,DISP=SHR
//SYSTSPRT DD   SYSOUT=*
Way 2
//STEP002    EXEC PGM=IKJEFT01             
//SYSTSPRT DD SYSOUT=*                     
//SYSTSIN  DD  *                           
    tso commands here


your-dataset would be the ps file having all the commands which needs to be executed
or  give all the commands in SYSTSIN DD *

Now if we explore further we can use this utility to perform many functions which in some cases may turn out to be very useful
Few useful commands which we can perform  in batch
1. Rename a dataset
2. Copy a file to some new name  (we can use other  ibm utilities as well)
3. Copy pds member to a new pds with a new name or same name
4 . Check job status and many other useful functions.
There are lot many others as well...
Have a look into jobs for some of the functions:
//STEP001    EXEC PGM=IKJEFT01                  
//SYSTSPRT DD SYSOUT=*                          
//SYSTSIN  DD  *                                
   SMCOPY FDS('USER12.JCL(TEST1)')  -           
          TDS('USER22.SAS(TEST2)') NOTRANS      

//SYSPRINT DD  SYSOUT=*                         
//SYSIN    DD  DUMMY                            
//* *****copy files                                            
//STEP002    EXEC PGM=IKJEFT01                  
//SYSTSPRT DD SYSOUT=*                          
//SYSTSIN  DD  *                                
   SMCOPY FDS('USER-ID.TST.FILE1')  -           
          TDS('USER-ID.TST.FILE2.FILE3') NOTRANS

//SYSPRINT DD  SYSOUT=*                         
//SYSIN    DD  DUMMY                            
 The  first step STEP001 copies pds members to other pds
The next step,STEP002 copies files
SMCOPY is the command to copy. FDS and TDS means From dataset and To dataset respectively.
Will explore some more and update as time permits!.

Saturday, October 11, 2014

File Handling in cobol - COBOL TUTORIAL

A data file is nothing but a collection of relevant records. Cobol reads the records line by line. Read the first line and process the entire logic,then read the second record and so on... Generally we use two types of file in our program.
1. Sequential files
2. Vsam Files
What is a sequential File ?
A sequential file is one whose records are in sequential order, from first to last. When we want to process this file, we need to start from the first records and go on sequentially. We can not delete and insert record in the middle suddenly. We can only add the records in the end.
Coming on to Vsam file, we have mainly 3 types which we use frequently in program.
a) KSDS  b) ESDS c) RRDS. We will see what they are and how to handle them in subsequent posts.

Coming back to Cobol file handling, let us see steps and ways to read/write files:
Before going into details, we need to know the bare essentials needed for file handling.
1. Assign the file to cobol program
2. Open the file (Either in input or output mode. There are other modes as well.Will see later)
3. Read the file into Working storage variables
4. Write the logic in procedure division as per the requirement
5. Write the output and Close the file.

The Very First step in writing a Cobol is to assign the Files . We all know that to run the cobol program ,we need JCL. So, JCL is the place where we give the actual physical file needed to run our program.
But, Our cobol  program need to understand this thing.
So this association between the JCL file and the cobol program is established in Environment Division using 'ASSIGN TO' Clause .The mapping with JCL DDNAME is done here. The file is allocated to our program by this ASSIGN Statement.
Next, the layout of the file and its attributes are defined in the FILE SECTION of DATA DIVISION. We should have a copybook to identify what value corresponds to what fields. That needs to be predefined in a copybook and should be included in the program using COPY statement.
Cobol Assign Clause
 But, before cobol uses these files for reading or writing, we need to OPEN these files with some keywords which will make cobol understand, whether the file is a input file or it will be used as an output file.
We need to use  these statements  in the procedure division to instruct cobol the kind of operation we will be performing on the files.
PROCEDURE DIVISION.
OPEN INPUT   CMF-FILE
     OUTPUT     OUT-FILE1
                         OUT-FILE2.   
Have a look into the JCL for better understanding of the file association between cobol and JCL.
Look for the DD names  CMFIN,FILE1, FILE2.
CMFIN is used with Dispostion of SHR which we are using as input in cobol
FILE1, FILE2 has Disposition of (NEW,CATLG,DELETE) which implies this file will be created new and hence opened in output mode in cobol code (above code)
//STEP0010 EXEC PGM=TSTCLAIM                         
//STEPLIB  DD DSN=MYSTEP1.BTCHLOAD,DISP=SHR          
//SYSOUT   DD SYSOUT=*                               
//SYSDBOUT DD SYSOUT=*                               
//CMFIN    DD DSN=TEST.CLAIM.INPUT,DISP=SHR        
//********  OUTPUT FILES  ******                     
//FILE1    DD TEST.OP1.CLAIM,                        
//         DISP=(,CATLG,DELETE),                     
//         DCB=(LRECL=205,RECFM=FB,BLKSIZE=0),       
//         UNIT=TEST,SPACE=(TRK,(15,15),RLSE)        
//FILE2    DD DSN=TEST.OP1.CLAIM,                    
//         DISP=(,CATLG),UNIT=&UNIT,SPACE=(TRK,(15,15)
//         DCB=(LRECL=110,RECFM=FB,BLKSIZE=0)        
//**** END  ********                                  
Back to cobol:  Once the above declaration is made, we can use the input file to read the input records one by one and process it.
READ CMF-FILE  INTO   W-CMF-CLAIMS-DETAIL     
     AT END   DISPLAY 'ERROR - EMPTY INPUT FILE !!!!!'
              STOP RUN.                              
 So, what is this  W-CMF-CLAIMS-DETAIL ?  This is the copybook which is defined for the input file. This READ statement dumps the every line of the input file into this structure , so that we can use these variables and process the data.

Lets see how does the READ statement work
Suppose your input file looks like:
20140924001102000560
20140924004214000560
20111003233513000560
20111217000439000560
20120814225039000560
20120602011643000560
20140924004214000560
 Simply by looking into these values wont make you understand what these digits are. But if we have a copybook, say  W-CMF-CLAIMS-DETAIL defined in the WORKING STORAGE of your cobol like below:
01 W-CMF-CLAIMS-DETAIL
     05 WS-CLAIM-DT  PIC X(08).
     05 WS-CLAIM-STATUS PIC X(06).
     05 WS-CLAIM-COMPANY PIC X(06).
Once we use the read statement for the very first time after the OPEN statement,like above
READ CMF-FILE  INTO   W-CMF-CLAIMS-DETAIL , the first 8 bytes of data will be placed in
WS-CLAIM-DT, next 6 bytes in WS-CLAIM-STATUS, and next 6 bytes in WS-CLAIM-COMPANY  Resulting in like below:
WS-CLAIM-DT will have the value 20140924
WS-CLAIM-STATUS will contain 001102
WS-CLAIM-COMPANY will contain  000560
Every time the read statement is performed, these values will get changed for the next record and so on  until EOF (End OF file) is reached.
Do All the processing as per the requirement in the procedure division and then the very last steps in this process would be writing the output file and closing all the files.
WRITE OUT-REC1 FROM WS-OUT-REC1
WRITE OUT-REC2 FROM WS-OUT-REC2.
CLOSE CMF-FILE-IN
      OUT-FILE1  
      OUT-FILE2.