Showing posts with label JCL. Show all posts
Showing posts with label JCL. Show all posts

Friday, October 6, 2017

Interpreting TSO ISRDDN command in mainframe ISPF

The TSO ISRDDN command is a useful tool that lets you browse/view your active TSO session libraries. From any session, type TSO ISRDDN and the below widow will open up.




















 On the right side of the display is a list of DDNAME(in white colour)  and their associated data sets ( (in Green colour) currently allocated to the user session.
**Dataset names in green are blurred on purpose

 The left side of the display contains columns of information about individual data sets like the volume information and all. When you scroll right (using F11)or left(or F10) , the left side of the screen changes. Initially, the left side of the screen contains the volume name and disposition,if the dataset is SMS managed or not ,etc . If the disposition is red, there are other jobs waiting to use this data set as shown. 

Generally the dataset associated with sysproc ddname contains the pds for the clist macros available in the system.

Try issuing  the command LINKLIST or LPA. Either command will add both the system LINKLIST and LPA libraries to the display.The LINKLIST and LPALIB (Link Pack Area LIBrary) are related concepts. The LINKLIST is a collection of libraries, established during the IPL, that contain system and user load modules. Any program in the LINKLIST does NOT require a JOBLIB or STEPLIB to point to the load library -- the system can find such programs without any JCL statements. The LPALIB basically contains read-only programs (which may system or user load modules) that are reenterable.

Saturday, March 19, 2016

DB2 unload utility using the program DSNTIAUL

IBM provides two methods of unloading data from a DB2 table. One is DSNTIAUL program that is run under IKJEFT01 or IKJEFT1A, or 1B and the other being  DSNUTILB program. DSNUTILB is a fairly new and is considered IBM’s Fast Unload Utility. Each has unique functionality that you may want to explore prior to choosing one. 

Outlined below are functions of DSNTIAUL process. 

1. DSNTIAUL Program: The DSNTIAUL program allows two type of unloads to be invoked against a DB2 table. When invoking DSNTIAUL you may specify an entire table unload or a selective SQL unload. The key DD statements that are being used are the SYSIN and the SYSTSIN. Both types of unloads are being run under IKJEFT1B.

Basic JCL example:
//UNLOAD EXEC PGM=IKJEFT1B, DYNAMNBR=20
//STEPLIB DD DSN=SYSDB2.DQA0.SDSNLOAD, DISP=SHR
// DD DSN=SUBSYS.DB2.DSNEXIT, DISP=SHR
//*************************************************************
//SYSPRINT DD SYSOUT=*
//SYSTSPRT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSREC00 DD DSN=userid.tablerecords.dataset,
//          DISP=(,CATLG,DELETE),
//       UNIT=SYSDA,SPACE=(CYL,(300,300),RLSE)
//*
//SYSPUNCH DD DSN=user-id.tablelayout.dataset,
//     UNIT=SYSDA,SPACE=(CYL,(1,1),RLSE),DISP=(,CATLG,DELETE)
//SYSTSIN DD *
SYSTEM (SUBSYS) RUN PROGRAM (DSNTIAUL) PLAN (DSNTIAUL) -
LIBRARY (‘SUBSYS.DB2.RUNLIB.LOAD’)
END
//SYSIN DD *
DBCREATOR.TABLENAME 
/*
//*


For selective Unload, like when you are using a where clause or using select statements (like SELECT * from user_table;)  we need to use PARM('SQL') in SYSTSIN statement; else you may endup with SQLCODE -104.
Your SYSTSIN would look like

//SYSTSIN DD *
SYSTEM (SUBSYS) RUN PROGRAM (DSNTIAUL)
         PLAN (DSNTIAUL) -
LIBRARY (‘SUBSYS.DB2.RUNLIB.LOAD’) PARM('SQL')
END 
//SYSIN DD *
SELECT * FROM schema.Tablename ;

Thursday, February 18, 2016

TSO WHOHAS code in REXX

Sometimes we face job abends, or job waiting for resource owing to the fact that some datasets get into contention with some other jobs or some user is using that particular file. Most of the organizations use TSO WHOHAS command to check the user holding the dataset. In this post we will see the piece of code in REXX which makes the command work.

/* REXX*/
DSNAME = ARG(1)
IF DSNAME = ' ' THEN DO
          SAY  'ENTER DATASET NAME'
PARSE UPPER EXTERNAL DSNAME
END
ADDRESS TSO
IF SYSDSN("'"DSNAME"'") <>  'OK' THEN DO
    SAY "DATASET DOES NOT EXIST"
    ADDRESS ISREDIT
    EXIT
END
ADDRESS TSO "ISRDDN E  ' "DSNAME" ' "
EXIT
Simple piece of code and it uses ISRDDN utility. It is an IBM utility which lists all the allocated DDNAME for your current TSO session.

Without the rexx code also , we even can execute the command
TSO ISRDDN ENQ 'Data-set Name'
and it will show the corresponding information

Saturday, January 2, 2016

Invoke CA7 commands from Batch terminal - use of SASBSTR

CA7 is a product of Computer Associates and is a scheduling tool for batch jobs in mainframe. When the number of jobs to be executed are astronomical, it is difficult to manage the jobs manually. So we need a tool like CA7 to manage the same. Manipulation of jobs, predecessor and triggers are done through CA7 panels. But sometimes we need to define hundreds of jobs to CA7, it is advisable to use batch terminal to do the same. Also batch terminals are less prone to errors. Batch terminals are a set of CA7 commands in a member of a partitioned dataset which is input to a CA7 batch program and submitted using a JCL

The program which executes the CA7 commands in batch is called SASSBSTR. The list of commands are put into a member of a partitioned dataset and given as an input to the program through SYSIN DD statement in the JCL. When executing the SASSBSTR program, the SYSIN input statements are copied into the input dataset called CA7. Communication dataset informs CA7 that there are commands waiting in the input dataset. These are read and processed by CA7. Any output is written to the output dataset. When all the commands have been processed, SASSBSTR copies the contents of the output dataset to SYSPRINT. Have a look into the below diagram
CA7 commands from batch terminal


Now, lets have the JCL to execute the CA7 from batch terminal.

//@SASBSTR EXEC PGM=SASBSTR
//UCC7CMDS DD DSN=TTOS.NCA7A01.COMMDS,DISP=SHR
//SYSDUMP DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSIN DD *
LJOB,JOB=SJABCD7,LIST=ALL     <==  CA7 command goes here
/*
//*

All relevant information for the particular job SJABCD7 will be listed in SYSOUT since we gave SYSPRINT DD SYSOUT=*.

Check the commonly used CA7 commands in this page. We can use these commands in the SYSIN DD* statements.

Explanation of JCL:
SASSBSTR is the program which executes the batch terminal
UCC7CMDS DD statement is a communication dataset which is used to read the CA7 commands from SYSIN DD Statements into the input dataset.

The CA7 commands are embedded within the SYSIN DD statement.All valid commands can be used here. Usually the programs are written in a cataloged procedure and the batch terminal is given as an input to the program. The output can be stored in a dataset.

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.

Convert VB file to FB and Convert FB file to VB using SORT

The below JCL copies the VB file to FB file.

//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INPUTVBFILE,DISP=SHR
//SORTOUT DD DSN=OUTPUTFBFILE,DISP=SHR
//*
//SORTWK01 DD SPACE=(CYL,10),UNIT=SYSDA
//SYSOUT DD SYSOUT=*
//SYSIN DD *
SORT FIELDS=(5,76,CH,A)
OUTFIL FNAMES=SORTOUT,VTOF,BUILD=(5,76)
/*

The INPUTVBFILE is a VB file with record length 80.
The OUTPUTFFBFILE is a FB file of record length 76.
Before executing the JCL it is assumed that both the SORTIN and SORTOUT datasets exists.
SORT FIELDS=(5,76,CH,A) sorts the input VB file.
VTOF will handle copying the VB file to FB file.
It is essential to give BUILD or OUTREC parameter when VTOF parameter is used.

Below JCL will Convert FB file to VB

//STEP01 EXEC PGM=SORT
//SORTIN DD DSN=INPUTFBFILE,DISP=SHR
//SORTOF01 DD DSN=OUTPUTVBFILE,
// DISP=(NEW,CATLG,DELETE),
// UNIT=SYSDA,
// DCB=(LRECL=80,RECFM=VB,BLKSIZE=84),
// SPACE=(TRK,(3000,2000),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
OUTFIL FNAMES=SORTOF01,FTOV

It is not essential to give BUILD or OUTREC parameter when FTOV parameter is used.

Tuesday, August 4, 2015

Can we delay the execution of a mainframe job?OPSWAIT is an option

Have you ever tried to keep a job or certain steps in a job to wait for sometime and then execute without using any scheduler ?

When would it be useful to ask mainframes to sleep like this?

Few days back ,came across a specific scenario when it was needed to put a job step on hold for sometime and then execute it.

Say for unit testing you want to execute two jobs in certain instance to check dataset conflict or table conflict.
Suppose we have a job with 3  steps. We want to execute step1 an then wait for sometime, say 1 minute, and then execute the remaining 2 steps. How do we do it ?

OPSWAIT is the option which can help us in this scenario.  (We need CA tool to be installed in our environment).
The OPSWAIT function suspends processing of the program or rule for a specified period in an OPS/REXX program or REQ rule.This  function can be used in OPS/REXX, AOF rules, TSO/E REXX, or CLIST.

//Jobcard..
//PSTEP01 EXEC PGM=TSTPGM
...
//PSTEP02  EXEC PGM=OPSWAIT,PARM='FOR(01:00)'
//PSTEP03  EXEC PGM=TSTPGM2
....
Once you submit this JCL, it till execute the step PSTEP01,then it will cause the mainframe to sleep for 1 min and then execute step 2.
We can try this command going into TSO command (option 6) and typing OPSWAIT 01:00.(01=mins,00=seconds)

We can also use this JCL to put the program on hold.
//SLEEP EXEC PGM=IKJEFT01 
//SYSPRINT DD SYSOUT=* 
//SYSTSPRT DD SYSOUT=* 
//SYSTSIN DD * 
OPSWAIT FOR(01:10) 
//* 

Wednesday, July 1, 2015

What is SMS in mainframe ? SMS stands for Storage Management Subsystem

Introduction:
The Storage Management Subsystem (SMS) automates the use of storage for data sets.  The z/OS ,  system is not aware of how much space a dataset will need, where it will be stored(Disk or Tape) ,what will be its record format and other details. Z/oS storage team need to decide whether to backup the large files and also need to recall it when necessary. All these data management activities can be done either manually or through the use of automated processes which is nothing but SMS.  With SMS activated , the z/OS  programmer or storage admin team  may, for example, create model data definitions for typical data sets, so that SMS automatically assigns those  attributes to data sets when they are created.
The data sets allocated through SMS are called system-managed data sets or SMS-managed data sets. For example, suppose you want to create a new data set named DATA.LIST. If SMS is active, you could use JCL like this:
//NEWDS DD DSN=myid.test.dataset1,
// DISP=(NEW,CATLG),
// DATACLAS=DCSL002,
// STORCLAS=SRTCL00

In this case, z/OS can use characteristics from predefined data and storage classes when it creates the DATA.LIST data set.

If SMS is not active or not in use, you need to manually specify the space requirements and storage location for the new data set, and your JCL would look like this :
//NEWDS DD DSN=myid.test.dataset1,
// DISP=(NEW,KEEP),
 // SPACE=(CYL,(1,1)),
 // UNIT=SYSDA,
// VOL=SER=SHARED  

The advantages associated with an SMS environment.
 • The user is relieved of making decisions about resource allocation of data sets, since it is done by SMS.
 • SMS provides the capability of concatenating data sets of unlike devices. For example, a tape data set can be concatenated with a disk data set. This capability is not available in a non-SMS environment.
 • SMS managed data sets cannot be deleted unless they are first uncataloged. Due to this extra step, erroneous deletion of data sets is minimized.
 • Additional features are available in the use of IDCAMS in an SMS environment. For example, the ALTER command can be used to increase the limit of the number of generation data sets in a GDG. This feature is not available in a non-SMS system.
 • VSAM data sets created in an SMS environment offer more flexibility that those created through JCL in a non-SMS environment.

Read about the  SMS Parameters in the next post

An overview of SMS parameters: STORCLAS,DATACLAS,MGMTCLAS,RECORG

1. The STORCLAS Parameter:
STORCLAS is a keyword parameter. It is used to assign a data set to an SMS defined class. 
These parameters discused below have significance only if SMS is active, otherwise it is ignored. 
Here’s the syntax: 
STORCLAS = class
Where class is an installation defined name and can be one to eight characters long. Use of this parameter results in the data set defined in the DD statement within that job being SMS-managed. The VOLUME and UNIT parameters can be omitted, since these values are now SMS supplied.
As we can see in the below example, VOLUME and UNIT parameters are omitted. These parameters will be installation defined for the class SMS1.
//JOB1 JOB (A123), ‘Ryan’
//STEP1 EXEC PGM=PROGRAM1
//DD1 DD DSN=myid.test.dataset1,
// DISP=(NEW, CATLG, DELETE),
// SPACE=(CYL, (1,1), RLSE),
// LRECL=80,
// RECFM=FB,
// STORCLAS=SMS1 

2. The DATACLAS Parameter:
DATACLAS is a keyword parameter. It is used to define any or all of the following parameters for a data set.(Marked in blue)
LRECL, RECORG , RECFM,  RETPD or EXPDT ,VOLCOUNT (coded on the VOL parameter) , 
SPACE , AVGREC
 Volcount is coded on VOL parameter. It is used to specify the number of tape volumes that can be mounted when a tape data set is being created or expanded.
For SMS managed VSAM data sets, DATACLAS can be used to define the following parameters: CISIZE, IMBED ,REPLICATE, SHAREOPTIONS ,FREESPACE 

Here’s the syntax of the DATACLAS parameter:
DATACLAS = class
Class is installation defined with predefined values for any of the above parameters

Suppose a class named GENERAL contains the following definitions:
SPACE = (CYL, (1,1), RLSE),
DCB= (RECFM=FB, LRECL=80)
My job uses the Class GENERAL in JCL

//JOB1 JOB (A123), ‘Ryan’ /
/STEP1 EXEC PGM=PROGRAM1
//DD1 DD DSN=myid.test.dataset1,
// DISP=NEW, CATLG, DELETE),
// UNIT=SYSDA,
// DATACLAS=GENERAL 

3. The MGMTCLAS Parameter 
This parameter is used to provide a management class for the associated data set coded in the DD statement. A management class is used to control the migration of data sets, the frequency of back ups, the number of backups versions, and the retention criteria of backup versions.
Here’s the syntax:
MGMTCLAS = class
It can be one to eight characters long. Parameters defined for this class can not be overridden. Example:
//JOB1 JOB (A123), 'Ryan’
//STEP1 EXEC PGM=PROGRAM1
//DD1 DD DSN=myid.test.dataset2
// DISP=(NEW, CATLG, DELETE),
// DATACLAS=GENERAL,
// MGMTCLAS=ARCHIVE

4. The LIKE Parameter:
 This parameter is used to copy attributes from an existing cataloged data set to a new data set. The following attributes can be copied over: SPACE RECFM AVGREC LRECL

Here’s the syntax:
LIKE = model.dataset
Where model.dataset identifies the name of the model data set.
Example:

//JOB1 JOB (A123), ‘Ryan’
//STEP1 EXEC PGM=PROGRAM1
//DD1 DD DSN=myid.test.dataset3,
// DISP=(NEW, CATLG, DELETE),
// LIKE=TEST.MODEL
 In this example, the  attributes of the data set TEST.MODEL is copied to the new data set called TEST.DATA2.

Wednesday, June 17, 2015

Copy empty Vsam file using SORT without error - Use of parameter VSAMEMT=YES in SORT

Once came across a scenerio where we had to copy a vsam file to a flat file and then process the flat file in subsequent steps.This is pretty simple and can be achived with a SORT step.But Once the same job abended when the VSAM file was emprty.
Came across this parameter VSAMEMT=YES which can be used with sort to handle this scenerio.

//STEP3 EXEC PGM=SORT,PARM=’VSAMEMT=YES’
//*
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=XXX.TEST.VSAM,DISP=SHR
//SORTOUT DD DSN=TEST.FLATFILE.COPY,DISP=MOD
//SYSIN DD *
SORT FIELDS=COPY
/*

Friday, April 10, 2015

Create Dataset name dynamically using system date and time or timestamp - using EZACFSM1

Many times we face the scenario, where we are in need to create a file suffixed with today's date ,time ,ie  the system date and time. It can be done in various ways. In this post we will see how to use one utility EZACSFM1 to achieve the same. It is a good utility and accepts many parameters which can be used tactfully to achieve good results.

//JOHNEZC JOB 1,'TEST', CLASS=I,NOTIFY=&SYSUID
//STEP1        EXEC PGM=EZACSFM1
//SYSOUT DD SYSOUT=(,INTRDR)   <= submit the below job via internal reader
//SYSIN DD DATA,DLM='..'
//TTEST JOB 1,'EZACSFM1',CLASS=I,NOTIFY=&SYSUID
//STEP2        EXEC PGM=IEFBR14
//MYDATA  DD DSN=TEST.DATA.D&DAY.M&LMON ,
//                          DISP=(,CATLG,DELETE),
//                         SPACE=(CYL,(10,10),RLSE),
//                         DCB=(RECFM=FB,LRECL=10,BLKSIZE=0)
(Tested code. Runs fine)
Explanation:
We are submitting the IEFBR14 job to create the dataset  TEST.DATA.DMON.M04 via internal reader as mentioned above.
If you see, i have  kept 'D&DAY' and  'M&LMON' in blue. Just to keep our attention there. The utility EZACSFM1 substitutes the value of day and month values there which will be created dynamically. &day, &lmon are the parameters of the utility.
If we submit the job, two jobs will be submitted. The first job will submit the second job creating the dataset with IEFBR14 dynamically with the date and time parameters.

To display the values in spool in sysout, try this piece of code.We will come across more options.
<Tested code >
//STEP1     EXEC PGM=EZACFSM1      
//SYSOUT    DD  SYSOUT=*          
//SYSIN     DD  *                
&YR.-&LMON.-&LDAY
&YR./&LMON./&LDAY
DATE IS : &YR.&LMON.&LDAY
/*
//
Some more parameters which EZACFSM1 takes. There are many more.

 '&DAY'                
 '&HHMMSS'              
 '&HR'                  
 '&JOBNAME'          
'&SEC'              
'&SEQ'                
'&YYMMDD'            
Test these small piece of code.M sure, you will find it very useful!!!

Thursday, March 12, 2015

Difference between PDS and PDSE - Brief discussion

We all know that a PDS (partioned data set), commonly referred to as Library in Z/OS world is a collection of several data sets which we call as members. A PDS internally contains a directory which keeps track of the member names.
A PDS is created with a Data Set Organization of PO , (DSORG=PO), which stands for partitioned organization.

Creating PDS using 3.2 option
Directory blocks  . . 20
Data set name type  : PDS
Using JCL:
SPACE=(TRK,(50,10),20)

However a PDS have certain disadvantages:
1. When we delete a member from a PDS, the space remains unused. We need to compress the PDS using 'Z' at the command line , or we can use IBM utility  IEBCOPY to reclaim the unused space.

2. Also as we know, a PDS internally contains a directory. As the size of the PDS grows, ie, as we add more and more members into the pds, the directory size gets near to the threshold (This Directory size we give when we define a PDS), after which we can not add any more members in the PDS.
Then we need to copy all the members into a new PDS with increased Directory size.

PDSE ( partitioned data set extended ):  Exactly same as PDS in many respects.
However , PDSE  data sets can be  stored only on DASD, not on tape. Interesting thing is the directory can expand automatically  as needed. Additionally it has an index which helps to locate the members inside the PDSE faster . SPACE from deleted members are automatically reused in PDSE .

PDSE files have DSORG=PO and DSTYPE=LIBRARY.
JCL to create PDS
//ALLOC    EXEC  PGM=IDCAMS
//SYSPRINT DD    SYSOUT=A
//SYSIN    DD    *
    ALLOC -
    DSNAME(TEST.PDSE1.EXAMPLE1) -
    NEW -
    STORCLAS(RM06) -
    MGMTCLAS(RM06) -
    DSNTYPE(LIBRARY)

Thursday, February 5, 2015

Copy members of PDS using IEBPTPCH

This JCL will copy the members of the PDS into a PS file with the help of IEBPTPCH

//STEPNAME EXEC PGM=IEBPTPCH                 
//SYSPRINT DD SYSOUT=*                       
//SYSUT1   DD DSN=TEST.PDS1,DISP=SHR  
//SYSUT2   DD DSN=TEST.PS1,          
//     DISP=(NEW,CATLG),                     
//     SPACE=(CYL,(50,50,)),                 
//     DCB=(RECFM=FB,LRECL=133,BLKSIZE=1330),
//     UNIT=WORK                             
//SYSIN    DD *                              
    PUNCH TYPORG=PO                          

Tuesday, February 3, 2015

Sort JCL to split every alternate records

 This JCL will split the even and the odd number of records from the input file.

//STEP01   EXEC PGM=SORT                             
//SYSOUT   DD SYSOUT=*                               
//SORTWK01  DD UNIT=DISK,SPACE=(CYL,(100,100))       
//SORTIN    DD *                                     
1111111111111111111111111                            
2222222222222222222222222                            
3333333333333333333333333                            
4444444444444444444444444                            
5555555555555555555555555                            
6666666666666666666666666                            
//ODD       DD DSN=TEST.ODD.OP1,
//          DISP=(,CATLG),UNIT=TEST,                 
//          SPACE=(CYL,(50,50),RLSE)                 
//EVEN       DD DSN=TEST.EVEN.OP2,
//          DISP=(,CATLG),UNIT=TEST,                 
//          SPACE=(CYL,(50,50),RLSE)                 
//SYSIN     DD *                                     
  SORT FIELDS=COPY                                   
  OUTFIL FNAMES=(ODD,EVEN),SPLIT                     
//*   

Here is the output of the ODD file:

******************************
1111111111111111111111111    
3333333333333333333333333    
5555555555555555555555555    
******************************

Here is the output of the EVEN  file:

**************************
2222222222222222222222222
4444444444444444444444444
6666666666666666666666666
**************************
SPLIT parameter to put the first record into OUTPUT1, the second record into OUTPUT2, the third record into OUTPUT1, the fourth record into OUTPUT2, and so on until you run out of records. SPLIT splits the records one at a time among the data sets specified by FNAMES.
Other options SPLITBY and SPLIT1R are also available. Do check out the usage for further info.

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!.

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 ........

Friday, June 6, 2014

Output statements using IF ELSE WHEN Clause in SAS - Creating multiple outputs in SAS

Sometimes we need to create multiple outputs in SAS depending on the IF ELSE conditions.The below JCL shows how to achieve this.
//SAS       EXEC SAS                    
//RYAN1     DD DSN=TEST.INPUT.SAS

//SYSOUT    DD SYSOUT=*                     
//SYSIN     DD *                

OPTION NOCENTER;                            
DATA DATA1;                                 
  INFILE RYAN1 MISSOVER;                    
  INPUT @6    POLNO     $CHAR10.            
        @10   CODE      $CHAR04.            
        ;                                   
  DATA EX1 EX2;                             
  SET DATA1;                                
  IF CODE='3992' THEN OUTPUT EX1;        
  IF CODE='T100' THEN OUTPUT EX2;       
  PROC PRINT DATA=EX1;                      
    TITLE 'EX1';                            
  PROC PRINT DATA=EX2;                      
    TITLE 'EX2'; 

Points to note: Both the output datasets, which we want to create should be mentioned in the DATA step. Here EX1 and EX2 are the ones.
Now, we can directly route these outputs to the output datasets as well.

Just a try with SELECT  WHEN clause in SAS  to get the same result.
OPTION NOCENTER;                 
DATA DATA1;                      
  INFILE RYAN1 MISSOVER;          
  INPUT @6    POLNO     $CHAR10. 
        @10   CODE   $CHAR04. 
        ;                        
  DATA EX1 EX2 EX3;              
  SET DATA1;                     
   SELECT (CODE);             
       WHEN  ('3992')  OUTPUT EX1;
       WHEN  ('1002')  OUTPUT EX2;
       OTHERWISE OUTPUT EX3;     
   END;                          
  PROC PRINT DATA=EX1;           
    TITLE 'EX1';                 
  PROC PRINT DATA=EX2;           
    TITLE 'EX2';                 

Thursday, March 27, 2014

SAS in Mainframes(z/Os) Tutorial with xamples - Part 2 ( Creating csv/excel file from mainframe dataset using SAS)

1. We will see how we can Merge two or more  input files in SAS and routing it to one output dataset and USE the same dataset to prepare a report in excel format
Creating .xls file on Z/os
(Refer to  Previous  posts to know basic steps in sas)
Lets take two input file, RXX.TEST.FILE3 and RXX.TEST.FILE4 with the fields
CITY,DATE,STATE,AMT in FILE3 and CITY,DATE,STATE,BANK in FILE4.We want to merge both the files so that the output contains CITY DATE STATE BANK.For achieving this, we need have atleast one common field in both the files based on which we can join these two datasets. We will be joining based on CITY.So the steps should be as follows.
Step1.Create the SAS dataset from input file 3 and SORT it on the key field
Step2.Create the SAS dataset from input file 4 and SORT it on the key field
Step3.create a new SAS dataset Using  the MERGE keyword in SAS along with the key field and finally
Step4. take the fields which we need

//SAS01     EXEC SAS                                
//POLIN    DD DSN=RXX.TEST.FILE3,DISP=SHR

//POLIN2   DD DSN=RXX.TEST.FILE4,DISP=SHR
//OUTFILE   DD DSN=RXX.TEST.FILEOUT,DISP=(,CATLG),
//             SPACE=(TRK,(20,20),RLSE),LRECL=180,RECFM=FB
//WORK      DD SPACE=(CYL,(50,10),RLSE)                   
//SYSIN     DD *   

OPTION NOCENTER;                   
OPTION SORTLIB='';                 
  DATA POLIN;                      
   INFILE POLIN;                   
   INPUT @01 CITY   $CHAR02.       
         @06 DATE   $CHAR08.       
         @14 STATE  $CHAR02.       
         @16 AMT    COMMA9.2;      
   PROC SORT DATA=POLIN NODUPS;    
     BY CITY;                                                          
  DATA POLIN2;                     
   INFILE POLIN2;                  
   INPUT @01 CITY   $CHAR02.       
         @06 DATE   $CHAR08.       
         @14 STATE  $CHAR02.       
         @16 AMT    COMMA9.2       
         @25 BANK   $CHAR5;        
                                   
   PROC SORT DATA=POLIN2 NODUPS;   
     BY CITY;                      
  DATA COMMON;                     
  MERGE POLIN(IN=D1) POLIN2(IN=D2);
  BY CITY;                         
  IF D1 AND D2 THEN OUTPUT;        
  PROC PRINT DATA=COMMON;          
     VAR CITY DATE STATE BANK;     
 RUN;                              
 DATA _NULL_;                           
    SET COMMON;                         
    FILE OUTFILE;                       
    PUT CITY ',' DATE ',' STATE ',' BANK;
RUN;                                    
Here goes the output for the same:
***********************
CA ,20130320 ,WB ,BANK1
CA ,20130120 ,TN ,BANK6
CA ,20130120 ,TN ,BANK6
CA ,20130320 ,KA ,BANK6
MI ,20130120 ,KA ,BANK1
MI ,20130320 ,AP ,BANK1
RR ,20130120 ,AP ,BANK8
************************

Why Do we use DATA _NULL_ in SAS ?  This simply is used when we want to make a report.
_NULL_  is a SAS keyword which does not create any SAS dataset.

2. Creating the excel report / CSV file from the mainframe dataset.
To add column headings in SAS to be used in excel sheet, we can use the DATA _NULL_ statement as well.
FILE OUTFILE  DLM=',';
IF _N_=1 THEN DO;
 PUT     'CITY,' 
         'DATE,'
         'STATE,' 
         'BANK'

;
END;

PUT  CITY 
     DATE
     STATE
     BANK
;

To Create a CSV File from a mainframe Dataset we can use the same above code with The delimiter option. DLM=','.(Imp point to remember. Delimeter is the key in creating .xls file)
 (If you remember we need to use delimited option in excel to prepare a formatted report from notepad. DLM option in SAS takes care of that ).
The line of code _N_=1 has special significance. We will check it later. However you can try running the program without using the specific line and see what happens.:)
So we  can download the dataset from command shell (option 6) in ISPF and use 'Receive from Host' option. Save the File in .csv format.
Or otherwise  put one FTP step (where u want to put the report) after the mainframe DATASET is created and save the file in filename_youwant.csv. No need to create a text file and convert it into excel sheet. The FTP location will contain the .xls file and ready to use!!

Saturday, March 1, 2014

OUTREC BUILD and OUTREC OVERLAY in SORT

We sometimes tend to get confused between the BUILD and OVERLAY of OUTREC statement.
Lets see  how each works and figure out when to use BUILD and OUTREC in SORT.
Scenario 1.
Input file is same as we used before
---+----1----+----2----+----3----+
************************  
HARLEY   123456MEXICO   
DAVID    658999CANADA    
*********************** 
We want to add date to the records from 35th position using BUILD.Sort syntax to do it with use of OUTREC BUILD would be:
SORT FIELDS=COPY                         
OUTREC BUILD=(1:1,32,35:&DATE)    
Output:
----+----1----+----2----+----3----+-          
*********************************
HARLEY   123456MEXICO   03/02/14
DAVID    658999CANADA   03/02/14 
********************************  
However,we can get the same output by use of OVERLAY in OUTREC as well like below:
SORT FIELDS=COPY                   
OUTREC OVERLAY=(35:&DATE)
Thus we can see, while using BUILD, we had to build the output records specifying the starting position,and records needed in output by using the syntax '1:1,32' and then specify '35:&date' which puts the date into 35th position.

However, OVERLAY reduced the coding effort.We specified only where the change needs to be done, keeping the entire record structure same.This becomes very handy when handling large and complex sort conditions since it eliminates the need to build the output record by record.