Portal | References | Downloads | Info | Programs | JCLs | Mainframe wiki | Quick Ref
IBM Mainframe Forum Index
 
Register
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Memberlist Profile Log in to check your private messages Log in
 
Add a step counter in a stack ?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    IBMMAINFRAMES.com Support Forums -> CLIST & REXX
View previous topic :: :: View next topic  
Author Message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Fri Jul 17, 2020 7:00 am    Post subject: Add a step counter in a stack ?
Reply with quote

Hi everyone, so this is my first post ever however I've been following this forum for so many years now and I always enjoy reading all the content.
So, HEY!

Basically, as I mentioned in the subject, I'm looking for a way to add a step counter inside my rexx stack, however, I reached a point where I'm not sure where to go from here.. basically, my rexx will read data from 2 datasets (source / target) and for each 1 row that is read on these datasets, 4 job steps are created, so first I do write a job card to the member and then once each dataset is read those from source/target the new 4 steps are created, so every time the stack resets and goes over again until it reaches the end of the file..

Is there a way to put a step counter for each step that it is generated, however, do not reset this counter ?? I was investigating MAKEBUFF command.. perhaps this is what I am looking for ??

Follow the code;

As you may see, each step has a STEP'S' on it, I tried putting a counter with S = 0 ; S = S + 1 but it didnt work due the stack I guess..

Appreciate the support if possible.

Thanks !

Code:

/*-------------------------------------------------------------------*/     
 "newstack"                        /*                                */     
 Outn=0                            /* Clear the variable  OutNumber  */     
 JobN=0                            /* Clear the variable: JobNumber  */     
/*--------------------------------*/                                         
 do dsn=1 to dsls.0                 /* init DataSetList for Source    */     
 do dsn=1 to dslt.0                 /* init DataSetList for Target    */     
                                                                             
    SRCName = WORD(DSLs.dsn,1)      /* Variable to identify source dataset */
    TGTName = WORD(DSLt.dsn,1)      /* Variable to identify target dataset */
                                                                             
/* QUEUE Below is used to generate steps whenever a dataset is read from     
   Source and Target members contained in JobLib                     */     
                                                                             
    QUEUE '//STEP'S'  EXEC PGM=IKJEFT01'                                     
    QUEUE '//SYSTSPRT  DD  SYSOUT=*'                                         
    QUEUE '//SYSTSIN   DD  *'                                               
    QUEUE ' PROF NOPREF '                                                   
    QUEUE ' HSEND FRRECOV FROMCOPYPOOL('CPNAME') - '                         
    QUEUE ' DSNAME('SRCName') - '                                           
    QUEUE ' NEWNAME('TGTName') '                                             
    QUEUE '//STEP'S'  EXEC PGM=IKJEFT01,DYNAMNBR=20            '             
    QUEUE '//SYSPROC  DD  DSN=DB2.CLONE.REXX,DISP=SHR  '               
    QUEUE '//SYSTSPRT DD  SYSOUT=*  '                                   
    QUEUE '//SYSTSIN  DD  * '                                           
    QUEUE '  %SLEEP 5 '                                                 
    QUEUE '//STEP'S'  EXEC PGM=IDCAMS '                                 
    QUEUE '//SYSPRINT DD   SYSOUT=* '                                   
    QUEUE '//SYSIN    DD   * '                                         
    QUEUE ' ALTER 'TGTNAME' STORCLAS(SCSTD) '                           
    QUEUE '//STEP'S'   EXEC PGM=IKJEFT01 '                             
    QUEUE '//SYSTSPRT  DD  SYSOUT=* '                                   
    QUEUE '//SYSTSIN   DD  * '                                         
    QUEUE '  PROF NOPREF '                                             
    QUEUE '  HMIGRATE ('TGTNAME') MOVE '                               
                                                                       
    if queued()//N_Split=0 then call Write                             
 end                               /*                                */
    if queued()>0 then call write  /*                                */
      cc=bpxwdyn('free dd('dd1')') /*                                */
 "delstack"                        /*                                */
 exit 0                            /*                                */
Back to top
View user's profile Send private message

prino

Senior Member


Joined: 07 Feb 2009
Posts: 1220
Location: Vilnius, Lithuania

PostPosted: Fri Jul 17, 2020 10:56 am    Post subject:
Reply with quote

Two do's, one end. Your code will not work.
Back to top
View user's profile Send private message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Fri Jul 17, 2020 11:25 am    Post subject: Reply to: Add a step counter in a stack ?
Reply with quote

Now that you mentioned... its weird but its working as I need.... will look into it thank you.. but still haven't figured out that counter thou.. :-(
Back to top
View user's profile Send private message
Willy Jensen

Active User


Joined: 01 Sep 2015
Posts: 387
Location: Denmark

PostPosted: Fri Jul 17, 2020 7:22 pm    Post subject:
Reply with quote

Variables are not affected by the stack. Both DOs are using the same control variable, surely that is not intended? And I can't see you setting the S variable anywhere. You need to initialise S before the first DO and then update it inside the second DO.
Back to top
View user's profile Send private message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Fri Jul 17, 2020 9:46 pm    Post subject:
Reply with quote

Thanks Willy for the tip, so I managed to add the step counter.
I know the code doesn't look perfect, I still need to go thru and review it and will spend some time always to improve and remove unnecessary stuff and adding more stuff, I always wanted to do coding so I am enjoying it each successful step (and learning with the bad choices lol)

So, following your tip, I managed to add the step counter.. but I got hit by another issue.. for each listed dataset in my input file, 4 steps are generated.. so the step counter is adding a value on a 4 step scale .. would there be a way to add one step counter for each one of the 4 steps ? like .. something continuous STEP1 , STEP2 , STEP3 , STEP4 , STEP 5 , STEP6.. perhaps create one variable for each of the 4 QUEUED steps ?

Here's the code now;

Code:

/*-------------------------------------------------------------------*/       
 "newstack"                        /*                                */       
 Outn=0                            /* Clear the variable  OutNumber  */       
 JobN=0                            /* Clear the variable: JobNumber  */       
 S=0                               /* Variable for Step Counter      */       
/*--------------------------------*/                                         
 do dsn=1 to dsls.0                 /* init DataSetList for Source    */     
 do dsn=1 to dslt.0                 /* init DataSetList for Target    */     
/**********************************/                                         
 If S>=0 then                       /* Init Step counter              */     
    do                                                                       
      S = S + 1                                                               
    end                                                                       
                                                                             
    SRCName = WORD(DSLs.dsn,1)      /* Variable to identify source dataset */
    TGTName = WORD(DSLt.dsn,1)      /* Variable to identify target dataset */
                                                                             
/* QUEUE Below is used to generate steps whenever a dataset is read from     
   Source and Target members contained in JobLib                     */       
                                                                             
    QUEUE '//STEP'S'  EXEC PGM=IKJEFT01'                                     
    QUEUE '//SYSTSPRT  DD  SYSOUT=*'                                         
    QUEUE '//SYSTSIN   DD  *'                                     
    QUEUE ' PROF NOPREF '                                         
    QUEUE ' HSEND FRRECOV FROMCOPYPOOL('CPNAME') - '             
    QUEUE ' DSNAME('SRCName') - '                                 
    QUEUE ' NEWNAME('TGTName') '                                 
    QUEUE '//STEP'S'  EXEC PGM=IKJEFT01,DYNAMNBR=20            ' 
    QUEUE '//SYSPROC  DD  DSN=DB2.CLONE.REXX,DISP=SHR  '         
    QUEUE '//SYSTSPRT DD  SYSOUT=*  '                             
    QUEUE '//SYSTSIN  DD  * '                                     
    QUEUE '  %SLEEP 5 '                                           
    QUEUE '//STEP'S'  EXEC PGM=IDCAMS '                           
    QUEUE '//SYSPRINT DD   SYSOUT=* '                             
    QUEUE '//SYSIN    DD   * '                                   
    QUEUE ' ALTER 'TGTNAME' STORCLAS(SCSTD) '                     
    QUEUE '//STEP'S'   EXEC PGM=IKJEFT01 '                       
    QUEUE '//SYSTSPRT  DD  SYSOUT=* '                             
    QUEUE '//SYSTSIN   DD  * '                                   
    QUEUE '  PROF NOPREF '                                       
    QUEUE '  HMIGRATE ('TGTNAME') MOVE '                         
                                                                 
    if queued()//N_Split=0 then call Write                       
 end                               /* end do for dsls (source)       */
    if queued()>0 then call write  /*                                */
      cc=bpxwdyn('free dd('dd1')') /*                                */
 end                               /* end do for dslt (target)       */
 "delstack"                        /*                                */
 exit 0                            /*                                */


Thanks again for all the valuable feedback.
Back to top
View user's profile Send private message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Fri Jul 17, 2020 9:59 pm    Post subject:
Reply with quote

Sorry for double post, just to provide an example on how the job gets created after running code updated provided in my last update;
So it will generate a STEP1 4 times , then moves to STEP2 4 times.. and so on .. what I'm trying to accomplish here is to setup some variables that for each step it will add a step counter and keep updating that counter once every dataset is referenced.

Code:

//*--------------------------------------------------------- 
//* Job generated by FRRECOV rexx program                     
//*--------------------------------------------------------- 
//STEP1  EXEC PGM=IKJEFT01                                   
//SYSTSPRT  DD  SYSOUT=*                                     
//SYSTSIN   DD  *                                             
 PROF NOPREF                                                 
 HSEND FRRECOV FROMCOPYPOOL(DSN$BHSAPPWS$LG) -               
 DSNAME(PWS1.ADSNLOAD) -                                     
 NEWNAME(SID1.ADSNLOAD)                                       
//STEP1  EXEC PGM=IKJEFT01,DYNAMNBR=20                       
//SYSPROC  DD  DSN=DB2.CLONE.REXX,DISP=SHR                   
//SYSTSPRT DD  SYSOUT=*                                       
//SYSTSIN  DD  *                                             
  %SLEEP 5                                                   
//STEP1  EXEC PGM=IDCAMS                                     
//SYSPRINT DD   SYSOUT=*                                     
//SYSIN    DD   *                                             
 ALTER SID1.ADSNLOAD STORCLAS(SCSTD)                         
//STEP1   EXEC PGM=IKJEFT01                                   
//SYSTSPRT  DD  SYSOUT=*                                     
//SYSTSIN   DD  *                                             
   PROF NOPREF                                   
   HMIGRATE (SID1.ADSNLOAD) MOVE                 
 //STEP2  EXEC PGM=IKJEFT01                       
 //SYSTSPRT  DD  SYSOUT=*                         
 //SYSTSIN   DD  *                               
  PROF NOPREF                                     
  HSEND FRRECOV FROMCOPYPOOL(DSN$BHSAPPWS$LG) -   
  DSNAME(PWS1.CONFIG.DWS1PSMP) -                 
  NEWNAME(SID1.CONFIG.DWS1PSMP)                   
 //STEP2  EXEC PGM=IKJEFT01,DYNAMNBR=20           
 //SYSPROC  DD  DSN=DB2.CLONE.REXX,DISP=SHR       
 //SYSTSPRT DD  SYSOUT=*                         
 //SYSTSIN  DD  *                                 
   %SLEEP 5                                       
 //STEP2  EXEC PGM=IDCAMS                         
 //SYSPRINT DD   SYSOUT=*                         
 //SYSIN    DD   *                               
  ALTER SID1.CONFIG.DWS1PSMP STORCLAS(SCSTD)     
 //STEP2   EXEC PGM=IKJEFT01                     
 //SYSTSPRT  DD  SYSOUT=*                         
 //SYSTSIN   DD  *                               
  PROF NOPREF                           
  HMIGRATE (SID1.CONFIG.DWS1PSMP) MOVE 
Back to top
View user's profile Send private message
Nic Clouston

Global Moderator


Joined: 10 May 2007
Posts: 2419
Location: Hampshire, UK

PostPosted: Sat Jul 18, 2020 1:46 am    Post subject: Reply to: Add a step counter in a stack ?
Reply with quote

Code:
    QUEUE ' DSNAME('SRCName') - '                                 
    QUEUE ' NEWNAME('TGTName') '                                 
    s = s + 1
    QUEUE '//STEP'S'  EXEC PGM=IKJEFT01,DYNAMNBR=20            ' 
    QUEUE '//SYSPROC  DD  DSN=DB2.CLONE.REXX,DISP=SHR  '         
Back to top
View user's profile Send private message
Willy Jensen

Active User


Joined: 01 Sep 2015
Posts: 387
Location: Denmark

PostPosted: Sat Jul 18, 2020 2:50 am    Post subject:
Reply with quote

Updated sample. I have made the assumption that the stems DSNL and DSLT are paired, so that source dataset 1 is in DSNLS.1 and target dataset 1 is in DSNLT.1, and so forth. Hence you only need one loop. Then I understand that you want each and every step number increased. The step number will be right-adjusted 4 bytes wide left-padded with 0. Finally I have used EXECIO directly instead of calling the WRITE routine. I hope that this is what you had in mind.
Code:
 "newstack"                        /*                                */     
 Outn=0                            /* Clear the variable  OutNumber  */     
 JobN=0                            /* Clear the variable: JobNumber  */     
 S=0                               /* Variable for Step Counter      */     
 do dsn=1 to dsls.0                /* init DataSetList for Source    */     
   SRCName = WORD(DSLs.dsn,1)      /* Variable to identify source dataset */
   TGTName = WORD(DSLt.dsn,1)      /* Variable to identify target dataset */
/* QUEUE Below is used to generate steps whenever a dataset is read from     
   Source and Target members contained in JobLib                     */     
   S = S + 1                       /* increase step nr               */     
   QUEUE '//STEP'right(s,4,0)'  EXEC PGM=IKJEFT01'                                     
   QUEUE '//SYSTSPRT  DD  SYSOUT=*'                                         
   QUEUE '//SYSTSIN   DD  *'                                                 
   QUEUE ' PROF NOPREF '                                                     
   QUEUE ' HSEND FRRECOV FROMCOPYPOOL('CPNAME') - '                         
   QUEUE ' DSNAME('SRCName') - '                                             
   QUEUE ' NEWNAME('TGTName') '                                             
   S = S + 1                       /* increase step nr               */     
   QUEUE '//STEP'right(s,4,0)'  EXEC PGM=IKJEFT01,DYNAMNBR=20'             
   QUEUE '//SYSPROC  DD  DSN=DB2.CLONE.REXX,DISP=SHR  '                     
   QUEUE '//SYSTSPRT DD  SYSOUT=*  '                                         
   QUEUE '//SYSTSIN  DD  * '                                                 
   QUEUE '  %SLEEP 5 '                                                       
   S = S + 1                       /* increase step nr               */     
   QUEUE '//STEP'right(s,4,0)'  EXEC PGM=IDCAMS '                                       
   QUEUE '//SYSPRINT DD   SYSOUT=* '                                         
   QUEUE '//SYSIN    DD   * '                                               
   QUEUE ' ALTER 'TGTNAME' STORCLAS(SCSTD) '                                 
   S = S + 1                       /* increase step nr               */     
   QUEUE '//STEP'right(s,4,0)'   EXEC PGM=IKJEFT01 '                                   
   QUEUE '//SYSTSPRT  DD  SYSOUT=* '                                         
   QUEUE '//SYSTSIN   DD  * '                                               
   QUEUE '  PROF NOPREF '                                                   
   QUEUE '  HMIGRATE ('TGTNAME') MOVE '                                     
   if queued()//N_Split=0 then "execio" queued() "diskr" dd1 /* write*/     
 end                               /* end do for dsls (source)       */     
 "execio" queued() "diskr" dd1 "(finis)"  /* write and close         */     
 cc=bpxwdyn('free dd('dd1')')      /*                                */     
 "delstack"                        /*                                */     
 exit 0                            /*                                */     

Question, why sub-setting the writes, do you really expect thousands of lines generated?
Back to top
View user's profile Send private message
Joerg.Findeisen

Active User


Joined: 15 Aug 2015
Posts: 342
Location: Bamberg, Germany

PostPosted: Sat Jul 18, 2020 3:16 am    Post subject:
Reply with quote

A job can have a maximum of 255 job steps. This maximum includes all steps in any procedures the EXEC statements call. icon_exclaim.gif

Also remove the unnecessary SLEEP step and modify the HSEND to make use of the WAIT parameter instead.
Code:
   QUEUE ' HSEND WAIT FRRECOV FROMCOPYPOOL('CPNAME') - '                         
   QUEUE ' DSNAME('SRCName') - '                                             
   QUEUE ' NEWNAME('TGTName') '
Back to top
View user's profile Send private message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Sat Jul 18, 2020 3:26 am    Post subject:
Reply with quote

Hi Willy ! The sample you wrote worked exactly the way I needed !
Thank you very very much for your help, and indeed, these source/target dataset records works in pair, so whenever a record is added on those steps from source, the same record (however with different HLQ) will be added on TGTNAME.

yes, in fact I'm expecting thousand lines to be retrieved but wanted to add the step counter so I can split the jobs across different members whenever it reaches the maximum number of 255 steps (240 is the number I've had in mind).

Also, thanks for explaining each update you've made to the sample, the good thing is that I was able to understand so I believe I'm getting there.

Thanks again!
Back to top
View user's profile Send private message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Sat Jul 18, 2020 3:28 am    Post subject:
Reply with quote

Joerg.Findeisen wrote:
A job can have a maximum of 255 job steps. This maximum includes all steps in any procedures the EXEC statements call. icon_exclaim.gif

Also remove the unnecessary SLEEP step and modify the HSEND to make use of the WAIT parameter instead.
Code:
   QUEUE ' HSEND WAIT FRRECOV FROMCOPYPOOL('CPNAME') - '                         
   QUEUE ' DSNAME('SRCName') - '                                             
   QUEUE ' NEWNAME('TGTName') '


Hi Joerg, thanks for the HSEND WAIT suggestion, I'll look into it and definitely remove the SLEEP step. Nice one !! Just added this sleep step because each step was processed to fast causing HSM to fail the next FRRECOV command.

Thank you so much!
Back to top
View user's profile Send private message
Joerg.Findeisen

Active User


Joined: 15 Aug 2015
Posts: 342
Location: Bamberg, Germany

PostPosted: Sat Jul 18, 2020 10:57 am    Post subject:
Reply with quote

@rodferrn: When you are able to issue DFHSM administrator commands, do not mix with user commands.

Change:
Code:
QUEUE '  HMIGRATE ('TGTNAME') MOVE '

to:
Code:
QUEUE '  HSEND WAIT MIGRATE DSN('TGTNAME') MOVE '
Back to top
View user's profile Send private message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Sat Jul 18, 2020 12:08 pm    Post subject:
Reply with quote

Joerg, I really have no words to thank you enough for all the good suggestions.

By removing the SLEEP step (it also reduced A LOT the number of steps in the jobs) and adding the HSEND WAIT command on both FRRECOV and MIGRATE it reduced the jobs runtime considerable, below, same number of steps and same datasets ;

Old run using sleep;
2.38 MINUTES EXECUTION TIME

New run without Sleep and adding WAIT parm
0.20 MINUTES EXECUTION TIME

Thank you folks!! Will keep trying my best ! icon_biggrin.gif
Back to top
View user's profile Send private message
Willy Jensen

Active User


Joined: 01 Sep 2015
Posts: 387
Location: Denmark

PostPosted: Sat Jul 18, 2020 5:04 pm    Post subject:
Reply with quote

Well, if you really want to reduce the number of steps, then remember that the ALTER command can also be issued from TSO. So you could run everything in one step. Or even from your REXX. Or write a small driver REXX doing one block of HSEND, ALTER and HMIGRATE and then your original REXX would just generate the call to that REXX. Many ways to skin that particular cat.
Back to top
View user's profile Send private message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Wed Jul 22, 2020 3:55 am    Post subject:
Reply with quote

Thanks for your feedback Willy, the problem I have in running everything in a single step is that, when it comes to multiple files (such as application vsam tablespace files) then I would need basically to double the amount of storage in my storage group, because first I would do the FRRECOV with newname (for all datasets) and then proceed with alter storage class and hsm move. So in order to have this workaround working I would need to treat each dataset at once after proceeding to the next one.

If you allow me to do a one more quick question, I'm trying to use the LMDINIT / LMDLIST for VSAM Cluster/Data however, even by coding the DSNDBC (to list only cluster datasets) still my output shows both cluster and data files, any ideas why ?

Follow the code;

Code:

"ISPEXEC LMDINIT LISTID(IDSID) LEVEL(SAP"SID".DSNDBC.*)"           
cnt=1                                                             
DO FOREVER                                                         
   "ISPEXEC LMDLIST LISTID("IDSID") OPTION(LIST) DATASET(DSSID) " 
   IF RC = 0 THEN                                                 
    DO                                                             
     DATA.CNT = DSSID                                             
     CNT = CNT + 1                                                 
    END                                                           
   ELSE LEAVE                                                     
END                                                               


Thanks again for all the amazing support and suggestions.
Att.
Back to top
View user's profile Send private message
Willy Jensen

Active User


Joined: 01 Sep 2015
Posts: 387
Location: Denmark

PostPosted: Wed Jul 22, 2020 2:02 pm    Post subject:
Reply with quote

Interesting, LMDLIST returns the data- and index components, even though they do not match the LEVEL parameter.
You can add STATS(YES) to LMDLIST and then test the ZDLSIZE variable for being null, meaning cluster.
Back to top
View user's profile Send private message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Fri Jul 24, 2020 12:46 am    Post subject:
Reply with quote

Hi Willy, thanks for you reply again, I've been reading about the STATS(YES) and ZDLSIZE but I'm still trying to make sense of those 2 lol.

Ugh, it is funny how we move from a plan to another when we are trying to design a solution .. I've just removed the N_Split variable because for that one I was spamming multiple jobs based on the number of rows, but once JCL has a 255 steps/execs constraint I have to limit jobs to 255, given the number of vsam cluster datasets I have for my application this might even generate hundreds of jobs.. so I'm looking into some way to run a single step where it invoke the rexx and the rexx script will run the 3 set of commands for all datasets ... right now I was trying to limit the jobs generation by step counter .. I tried IF S = 255 then call Write however this will limit one single job with 255 steps ..

Will look into something like you said (running a single JCL where the rexx is invoked and all commands are processed by the rexx itself).

Anyway, just with the good tips and suggestions this is how the procedure look so far ... (its small work but its decent work ha!) icon_biggrin.gif

Code:

/*********************************************************************/     
/* During program init insert copy pool name to generate frrecov jobs*/     
/*********************************************************************/     
SAY 'Insert Copy Pool name eg. DSN$BHSAPPWS$DB / DSN$BHSAPPWS$LG'           
PULL CPNAME                                                                 
CPNAME = CPNAME                                                             
                                                                           
/* If user does not provide CPNAME fail exec */                             
 IF CPNAME = '' THEN DO                                                     
                     SAY ' MISSING COPY POOL NAME '                         
                     SAY ' PLEASE REPEAT EXEC AND INPUT COPY POOL NAME '   
                     EXIT 16                                               
                END                                                         
/*-------------------------------------------------------------------*/     
 CC=BPXWDYN('ALLOC DA('JobLib'('SRCDSN')) SHR RTDDN(DD1)')                 
 "EXECIO * DISKR" DD1 "(STEM DSLs. FINIS)"                                 
 CC=BPXWDYN('FREE DD('DD1')')  /* Open SRC Member in PDS for data reading */
                                                                           
 CC=BPXWDYN('ALLOC DA('JobLib'('TGTDSN')) SHR RTDDN(DD2)')                 
 "EXECIO * DISKR" DD2 "(STEM DSLt. FINIS)"                                 
 CC=BPXWDYN('FREE DD('DD2')')  /* Open TGT Member in PDS for data reading */
/*-------------------------------------------------------------------*/     
 "newstack"                        /*                                */       
 Outn=0                            /* Clear the variable  OutNumber  */       
 JobN=0                            /* Clear the variable: JobNumber  */       
 S=0                               /* Variable for Step Counter      */       
/*--------------------------------*/                                         
 do dsn=1 to dsls.0                 /* init DataSetList for Source    */     
 do dsn=1 to dslt.0                 /* init DataSetList for Target    */     
/**********************************/                                         
                                                                             
    SRCName = WORD(DSLs.dsn,1)      /* Variable to identify source dataset */
    TGTName = WORD(DSLt.dsn,1)      /* Variable to identify target dataset */
                                                                             
/* QUEUE Below is used to generate steps whenever a dataset is read from     
   Source and Target members contained in JobLib                     */       
                                                                             
    S = S + 1                                                                 
    QUEUE '//STEP'right(s,4,0)'  EXEC PGM=IKJEFT01'                           
    QUEUE '//SYSTSPRT  DD  SYSOUT=*'                                         
    QUEUE '//SYSTSIN   DD  *'                                                 
    QUEUE ' PROF NOPREF '                                                     
    QUEUE ' HSEND WAIT FRRECOV FROMCOPYPOOL('CPNAME') - '                     
    QUEUE ' DSNAME('SRCName') - '                                         
    QUEUE ' NEWNAME('TGTName') '                                           
    S = S + 1                                                             
    QUEUE '//STEP'right(s,4,0)'  EXEC PGM=IDCAMS '                         
    QUEUE '//SYSPRINT DD   SYSOUT=* '                                     
    QUEUE '//SYSIN    DD   * '                                             
    QUEUE ' ALTER 'TGTNAME' STORCLAS(SCSTD) '                             
    S = S + 1                                                             
    QUEUE '//STEP'right(s,4,0)'  EXEC PGM=IKJEFT01 '                       
    QUEUE '//SYSTSPRT  DD  SYSOUT=* '                                     
    QUEUE '//SYSTSIN   DD  * '                                             
    QUEUE '  PROF NOPREF '                                                 
    QUEUE '  HSEND WAIT MIGRATE - '                                       
    QUEUE '  DSN('TGTNAME') MOVE '                                         
                                                                           
    CALL Write                                                             
                                                                           
 end                               /* end do for dsls (source)       */   
      cc=bpxwdyn('free dd('dd1')') /*                                */   
 "delstack"                        /*                                */   
 exit 0                            /*                                */   
/*-------------------------------------------------------------------*/     
/* ---  Start call Write      -------------------------------------- */     
/*-------------------------------------------------------------------*/     
Write:                                                                       
 Outn=Outn+1                       /*Add +1 to the OutNumber variable*/     
 Jobn=Jobn+1                       /*Add +1 to the JobNumber variable*/     
                                                                             
 say 'New Job 'NameRun''Outn' created at record' dsn 'will contain',         
     queued() 'records'  /* Print on user screen how many Jobs are created */
                                                                             
 CC=BPXWDYN('ALLOC DA('JobLib'('NameRun''Outn')) SHR DD('DD1') REUSE')       
                                                                             
 call JobCard                      /* CALL JobCard insert jcl card   */     
 "EXECIO" QUEUED() "DISKW" DD1 "(FINIS)"                                     
 Return 0                                                                   
/*-------------------------------------------------------------------*/ 
/*-------------------------------------------------------------------*/ 
/* ---  Start call JobCard    -------------------------------------- */ 
/*-------------------------------------------------------------------*/ 
JobCard:                                                                 
If Jobn>=0 then                                                         
   do                              /*                                */ 
     Jobn = Jobn + 0                                                     
   end                             /*                                */ 
jcl.1='//FRRC'Jobn'  JOB  (@HSG,BA01),SP3,CLASS=A,MSGCLASS=H,      '     
jcl.2='//         MSGLEVEL=(1,1),NOTIFY=&SYSUID,REGION=0M          '     
jcl.3='//*---------------------------------------------------------'     
jcl.4='//* Job generated by FRRECOV rexx program                   '     
jcl.5='//*---------------------------------------------------------'     
jcl.0=5                                                                 
                                   /*                                */ 
do n=jcl.0 to 1 by -1              /*                                */ 
   push jcl.n                      /*                                */ 
end                                /*                                */ 
Return                                                                   


PS. Btw this one doesnt have counter to limit each job by 255 steps.. I couldn't find that yet.. perhaps something simple.. but I need to go deep in my research and study.

Cheers folks!!
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2205
Location: Silicon Valley

PostPosted: Fri Jul 24, 2020 4:21 am    Post subject: Reply to: Add a step counter in a stack ?
Reply with quote

I do not like that variable DSN is used for both of these DO clauses. I think it should be two different variable names (though I did not examine the earlier logic thoroughly.

Code:
 do dsn=1 to dsls.0                 /* init DataSetList for Source    */     
 do dsn=1 to dslt.0                 /* init DataSetList for Target    */     


More likely, there is a one to one correspondence in your dsls. and dslt. stem variables. It seems more plausible that you only need one DO loop here.


Quote:
some way to run a single step where it invoke the rexx

I think you need to rely heavily on ADDRESS TSO to issue your commands.
Code:
Address TSO
'PROF NOPREF '             

/*--------------------------------*/                                         
Do dsn=1 to dsls.0                  /* init DataSetList for Source    */     
                                              /* init DataSetList for Target    */   
                                                                             
    SRCName = WORD(DSLs.dsn,1)      /* Variable to identify source dataset */
    TGTName = WORD(DSLt.dsn,1)      /* Variable to identify target dataset */   
     
    'HSEND WAIT FRRECOV FROMCOPYPOOL('CPNAME') ',
       'DSNAME('SRCName') ',
       'NEWNAME('TGTName') '

    'ALTER 'TGTNAME' STORCLAS(SCSTD) '

    'HSEND WAIT MIGRATE ',
       'DSN('TGTNAME') MOVE '

  End
End


The use of WAIT on FRRECOV makes this possible. I do not think WAIT on MIGRATE is needed unless you are very tight on storage.
Back to top
View user's profile Send private message
Willy Jensen

Active User


Joined: 01 Sep 2015
Posts: 387
Location: Denmark

PostPosted: Fri Jul 24, 2020 7:07 pm    Post subject:
Reply with quote

The double 'DO's have been noted before. Something else, if you just want to look at catalog info then you can use the IGGCSI00 program, which does not incur the cost of reading the VTOC like LMDLIST STATS(YES) does. IBM supplies a sample in SYS1.SAMPLIB(IGGCSIRX) , but there are numerous other implementations. Search this forum, or have a look at my CSIREXX here
Back to top
View user's profile Send private message
rodferrn

New User


Joined: 14 Jul 2020
Posts: 13
Location: Brazil

PostPosted: Wed Jul 29, 2020 6:18 am    Post subject:
Reply with quote

Hello Pedro and Willy, wow!! Thank you so much for all the input.
Using Adress TSO just resolved all my problems with step limit in JCL. icon_biggrin.gif

The more I work on this project the more I feel like learning and eager to improve the code. So, I've generated an input member (SRCSAP) containing 45K datasets of SAPsid.DSNDBC.** , running a single job with this exec (using address TSO) is working perfectly, but the first runtime took 4 hours to complete (not bad, definitely not bad) but looking to improve the code or the efficiency of the solution, I removed the WAIT parameter (as suggested by Pedro) and was able to reduce the runtime to 3 hours and a half.
Now, on a second test I compiled my rexx and I managed reduce that runtime even more.

Now, I am thinking about serializing my execution (still using address tso) but instead of processing a single source/target member I was thinking about doing a dataset count by 10k or 12k and after each 10-12k generate a new member in DB2.CLONE.NEW.sid;

The current solution (below) will generate one source and one target member and add all source datasets (45k) on the same member, so I am looking for a way to do (perhaps a NESTED LOOP ? ) to generate a new member lets say SRCSPx and TGTSPx once 10 or 12k files are read..

Would a nested loop resolve this ??

This is the current code;

Code:

"ISPEXEC LMDINIT LISTID(ID3) LEVEL(SAP"SID".DSNDBC.*)"               
                                                                     
cntid3=1                                                             
DO FOREVER                                                           
"ISPEXEC LMDLIST LISTID("ID3") OPTION(LIST) DATASET(DSNSAP)"         
   IF RC = 0 THEN                                                   
    DO                                                               
     DATAsap.cntid3 = DSNSAP                                         
     cntid3 = cntid3 + 1                                             
    END                                                             
   ELSE LEAVE                                                       
END                                                                 
                                                                     
  "ISPEXEC LMDLIST LISTID("ID3") OPTION(FREE)"                       
  "ALLOC DD("SRCSAP") DA(DB2.CLONE.NEW."SID"("SRCSAP")) SHR REU"     
  "EXECIO * DISKW  "SRCSAP" (STEM DATAsap. FINIS"                   
  "FREE DD("SRCSAP")"                                               
  "ALLOC DD("TGTSAP") DA(DB2.CLONE.NEW."SID"("TGTSAP")) SHR REU"     
  Push "TESTE"                                                       
  "EXECIO 1 DISKW "TGTSAP" (FINIS"                                   
  "FREE DD("TGTSAP")"                                               
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic    IBMMAINFRAMES.com Support Forums -> CLIST & REXX All times are GMT + 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 

Search our Forum:

Similar Topics
Topic Author Forum Replies Posted
No new posts Please help - SORT with SUM fields an... clearskynot DFSORT/ICETOOL 6 Thu Apr 09, 2020 11:01 am
No new posts Conditional step execution based on P... Lccole10 JCL & VSAM 9 Wed Feb 19, 2020 10:07 pm
No new posts proc step return code to override in ... Aaryaa JCL & VSAM 3 Tue Aug 20, 2019 4:32 pm
No new posts Having problem passing a variable to ... markzasz JCL & VSAM 12 Thu Jul 11, 2019 5:31 pm
No new posts How to force PULL to read user-input ... Andi1982 CLIST & REXX 5 Thu May 09, 2019 6:27 pm

Back to Top
 
Job Vacancies | Forum Rules | Bookmarks | Subscriptions | FAQ | Polls | Contact Us