Thursday, September 21, 2023

Easytrieve program has beaten SYNCSORT in the CPU performance

Recently I tried to replace an Easytrieve program with SYNCSORT for performance reasons.

The below Easytrieve program was running for 6 minutes and it issued 1,051,382 EXCP’s and consumed 15.84 CPU seconds.

The input file had about 60 million records.

FILE FILEIN                     
IN-REC          1  244  A  
IN-FIELD1     212    1  A      
IN-FIELD2     213   11  N 4    
IN-FIELD3     224    5  N      
IN-FIELD4     229   11  N 4    
IN-FIELD5     240    5  N      
FILE FILEOUT   FB(0 0)          
OUT-REC         1  246  A  
OUT-FIELD1    212    3  A  
OUT-FIELD2    215   11  N 4
OUT-FIELD3    226    5  N  
OUT-FIELD4    231   11  N 4
OUT-FIELD5    242    5  N  
 
JOB INPUT FILEIN                         
*                                        
OUT-REC = IN-REC                         
*                                        
IF IN-FIELD1  = ' '                
   OUT-FIELD1 = '   '               
ELSE                                      
   OUT-FIELD1 = 'XXX'             
END-IF                                   
*                                        
OUT-FIELD2 = IN-FIELD2   
OUT-FIELD3 = IN-FIELD3        
OUT-FIELD4 = IN-FIELD4   
OUT-FIELD5 = IN-FIELD5        
*                                        
PUT FILEOUT                              
 

I created below SORT card to replace the above program. SORT step completed in 2 minutes 45 seconds.

It issued 58,423 EXCPs and consumed 25.10 CPU seconds.

  OPTION COPY
  INREC IFTHEN=(WHEN=(212,1,CH,EQ,C' '),      
      BUILD=(1:1,211,C'   ',213,32)),           
      IFTHEN=(WHEN=NONE,
      BUILD=(1:1,211,C'BER',213,32))

 Below is the comparison 

EZT program

SORT

EZT program

SORT

EZT program

SORT

CPU time

CPU time

Elapsed time

Elapsed time

IO count

IO count

15.84 seconds

25.1 seconds

00:05:31

00:02:45

1,051,382

58,423

Though SORT has beaten EZT program by elapsed time, it could NOT beat when it comes to CPU time.

Thursday, September 7, 2023

How to use Symbolic parameter in JCL SYSIN card and in-stream datasets

Symbolic parameters can be used in the in-stream datasets. Unlike symbolic substitution in the JCL stream of a job, which is performed by the JCL converter during processing of JCL statements, in-stream symbolic substitution is performed by JES when an in-stream data set is read.

This is achieved by “EXPORT SYMLIST”, “SYMBOLS=JCLONLY” parameters.

Example 1


//TESTJOB JOB….
//*
// EXPORT SYMLIST=*
// SET HLQ1=USERID
//*
//DELETES EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *,SYMBOLS=JCLONLY
 DELETE &HLQ1..DSN1
 DELETE &HLQ1..DSN2
/*

Example 2

//REALLOC  JOB 1,TESTJOB,    
//          MSGLEVEL=(1,1),CLASS=A
//*
//E1  EXPORT SYMLIST=(DSNAME) 
//E2  EXPORT SYMLIST=(VOLSER)     
//S1  SET    DSNAME=HASP.TEST.MACLIB
//S2  SET    VOLSER=J2COM1
//*
//DEALLIB EXEC PGM=IDCAMS,REGION=300K 
//DD1       DD UNIT=3390,DISP=OLD,VOL=SER=&VOLSER
//SYSPRINT  DD SYSOUT=* 
//SYSIN     DD *,SYMBOLS=JCLONLY 
            DELETE  &DSNAME  
            NONVSAM PURGE SCRATCH FILE(DEVICE)
//*               
//REALLIB EXEC PGM=IKJEFT01,REGION=300K  
//SYSTSPRT  DD SYSOUT=*        
//SYSTSIN   DD *,SYMBOLS=JCLONLY 
            ALLOCATE DSNAME('&DSNAME.') 
            UNIT(3390) VOLUME(&VOLSER.) 
            NEW CATALOG DSNTYPE(LIBRARY)
            SPACE(65,15)  DIR(56)   TRACKS
/*

More information about this facility can be found in  

https://www.ibm.com/docs/en/zos/2.3.0?topic=symbols-using-in-jes-in-stream-data


How to copy VSAM KSDS, Alternate Index AIX, PATH files without using IDMCAS in an easy way

Suppose you want to copy VSAM KSDS, AIX, PATH files for your testing needs.
 
This involves following steps
 
1. Defining the KSDS file
2. Load the data to the base cluster
3. Define the alternate index and corresponding path
4. Build the alternate index
 
The below sample job uses IBM supplied utility ADRDSSU to dump the PROD.* files and restore them under TEST qualifier.
 
The end result is PROD.* files are copied to TEST.* files
 
//DUMPFLS  EXEC PGM=ADRDSSU                                 
//SYSPRINT DD SYSOUT=*                                      
//OUTF     DD DSN=DUMP.FILE,                        
//            DISP=(NEW,CATLG,DELETE),                       
//            UNIT=SYSDA,                                   
//            DCB=(RECFM=U,BLKSIZE=27998,LRECL=0,DSORG=PS), 
//            SPACE=(CYL,(50,50),RLSE)            
//SYSIN    DD *                                             
   DUMP DS(INC(PROD.MASTER.KSDS, -               
               PROD.MASTER.AIX1, -               
               PROD.MASTER.PATH1)) -             
   OUTDDNAME(OUTF)               -                          
   ALLDATA(*)                    -                           
   ALLEXCP                       -                          
   SPHERE                        -                          
   OPTIMIZE(4)                   -                          
   COMPRESS                      -                          
   TOL(ENQF)                                                
/*                                                          
//RESTRE  EXEC  PGM=ADRDSSU                       
//SYSPRINT DD SYSOUT=*                             
//INPF     DD  DSN=DUMP.FILE,DISP=SHR      
//SYSIN    DD *                                    
   RESTORE INDDNAME(INPF)              -           
   DS(INC (**))                        -           
   CAN CAT SHR REPLACE                 -           
   TOL(ENQF)                           -           
   SPHERE                              -           
   RENAMEU((PROD.MASTER.KSDS,   -       
            TEST.MASTER.KSDS) -       
           (PROD.MASTER.AIX1,   -       
            TEST.MASTER.AIX1) -       
           (PROD.MASTER.PATH1,  -       
            TEST.MASTER.PATH1))       
//*                                                

Wednesday, March 15, 2023

How to use COBOL occurs depending on working storage section table in a SQL query

Let us say we have below COBOL working storage section table and we want to match all the employee numbers from this array to a DB2 table.

01 W-EMP-COUNT   PIC S9(04) COMP.
01 W-EMP-LIST.
   05 W-EMP-NUM OCCURS 1 TO 50 TIMES DEPENDING ON W-EMP-COUNT
                 PIC X(05).

Below SQL does exactly that 

WITH TEMP(IDX, T_EMP_NUM) AS 
(SELECT 1, LEFT(:W-EMP-LIST,5)
     FROM SYSIBM.SYSDUMMY1 
   UNION ALL
SELECT IDX+1, SUBSTR(:W-EMP-LIST,((IDX)*5)+1,5)
     FROM TEMP
 WHERE IDX < :W-EMP-COUNT
),
SELECT * FROM EMP_TABLE, TEMP 
    WHERE EMP_NO  = EMP_NUM;

Find and replace using using TSO batch utility

Below job does find and replace using TSO batch utility. 

//STEP01 EXEC PGM=IKJEFT01
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSTSIN  DD *
  EDIT 'MY.DATA.SET' OLD NONUM CNTL
  VERIFY ON
  TOP
  C * 9999999 'LOG NO' 'LOG YES' ALL
  TOP
  C * 9999999 'INTO TABLE' 'RESUME YES INTO TABLE' ALL
  TOP
  C * 0000001 'RESUME YES INTO TABLE' 'REPLACE INTO TABLE'
  SAVE
//*

Friday, January 6, 2023

COBOL compile job produces user abend 4093 reason code X'1C'

COBOL compile job abends with below message.

A user abend 4093 reason code X'1C' occurred in module CEEPLPKA at offset X'7C214'.                                                       

This issue can be fixed by specifying REGION=0M in the JOB card.



Friday, April 8, 2022

COBOL code to test BIT setting in a BINARY field

The below COBOL code tests whether 31st bit in "0100 0000 0000 0000 0000 0000 0000 0000" is ON.
 
        WORKING-STORAGE SECTION.                                         
       ***************************************************************** 
       * DETERMINE THE VALUE IN A SPECIFIC BIT IN A FULLWORD.          * 
       *                                                               * 
       * - 'BIT-POINTER'. MOVE A VALUE TO THIS FIELD TO INDICATE       * 
       *       WHICH BIT YOU WANT TO TEST. BIT '0' IS THE LOW-ORDER    * 
       *       BIT AND '31' IS THE HIGH-ORDER.                         * 
       * - 'RESULT-FIELD'. CONTAINS A VALUE OF '0' OR '1', INDICATING  * 
       *       THE VALUE OF THE BIT TO WHICH BIT-POINTER IS POINTING.  * 
       *                                                               * 
       ***************************************************************** 
        01  FEEDBACK-CODE.                                               
            05 FC-SEVERITY                 PIC S9(4) BINARY VALUE +0.    
            05 FC-MESSAGE                  PIC S9(4) BINARY VALUE +0.    
            05 FILLER                      PIC X(08).                    
        01  WS-WORK-FIELDS.                                              
           05 INPUT-BINARY-FIELD             PIC S9(9) COMP-5.           
           05 BIT-POINTER                    PIC S9(9) BINARY VALUE +0.  
           05 RESULT-FIELD                   PIC S9(9) BINARY VALUE +0.  
        PROCEDURE DIVISION.                                              
            MOVE 1073741824 TO INPUT-BINARY-FIELD                        
            MOVE +30 TO BIT-POINTER.                                     
            MOVE +0  TO RESULT-FIELD.                                    
            CALL 'CEESITST' USING INPUT-BINARY-FIELD,                    
                                  BIT-POINTER,                           
                                 FEEDBACK-CODE,                         
                                 RESULT-FIELD.                          
           IF FC-SEVERITY = +0                                          
              DISPLAY 'VALUE OF BIT ' BIT-POINTER ' IS ' RESULT-FIELD   
           ELSE                                                         
             DISPLAY 'BAD RETURN FROM CEESITST '                        
             DISPLAY 'FEEDBACK SEVERITY = ' FC-SEVERITY                 
             DISPLAY 'FEEDBACK MESSAGE  = ' FC-MESSAGE                  
           END-IF.                                                      
           GOBACK.