Update Last Char in last Record of a Dataset



IBM's flagship sort product DFSORT for sorting, merging, copying, data manipulation and reporting. Includes ICETOOL and ICEGENER

Update Last Char in last Record of a Dataset

Postby golemis » Mon Feb 17, 2020 2:37 pm

Hi team,
I would appreciate your ideas on how I could update the very last character of the last record in a FB(80) dataset.
This dataset is the result of a split of a larger one, with each chunk having approx. 1/2 a million records, all of the same layout. For this reason, I cannot use 'IFTRAIL=' as there is nothing to identify the last record as a trail. And the last chunk contains an unknown number of remaining records. Each chunk has to replace its last character to a special one indicating the end of the dataset!
I am thinking of using (another) SUBSET to isolate the last record, update it, using OVERLAY or FINDREP, and then concatenate to the original-1 record set, but since this is a repetitive process that splits the dataset in multiple ones, and the last will have an unknown number of records, this gets a bit more complcated.
I wonder if there would be a simple method to update the last char of the last record, whitout using SUBSET.
Thank you
GG
golemis
 
Posts: 34
Joined: Wed Apr 04, 2018 8:13 pm
Location: London, UK
Has thanked: 10 times
Been thanked: 0 time

Re: Update Last Char in last Record of a Dataset

Postby NicC » Mon Feb 17, 2020 3:25 pm

Why do you need a special indicator to tell a properly written program that EOF has been reached? Why does the usual method of determining EOF not work?
The problem I have is that people can explain things quickly but I can only comprehend slowly.
Regards
Nic
NicC
Global moderator
 
Posts: 3025
Joined: Sun Jul 04, 2010 12:13 am
Location: Pushing up the daisies (almost)
Has thanked: 4 times
Been thanked: 136 times

Re: Update Last Char in last Record of a Dataset

Postby golemis » Mon Feb 17, 2020 3:29 pm

It is a dataset that will be xlated to ASCII. Every record finishes with x'1E' but this char has to be substituted with x'1D' for the last char of the last record.
golemis
 
Posts: 34
Joined: Wed Apr 04, 2018 8:13 pm
Location: London, UK
Has thanked: 10 times
Been thanked: 0 time

Re: Update Last Char in last Record of a Dataset

Postby sergeyken » Wed Feb 19, 2020 2:34 am

None of standard utilities do have an option to know in advance: if there are no more records in the dataset (e.g. to check if the current record is the last one, or not?)

For each task an appropriate tool needs to be chosen. In this case, the existing "IBM UTILITIES & TOOLS ‹ DFSORT/ICETOOL/ICEGENER" is not good choice.

The most simple way is REXX
/* REXX */
FIXUNIX:
"NEWSTACK"
"EXECIO * DISKR INDD (FINIS"
"EXECIO 0 DISKW OUTDD (OPEN"
Do iRec = 1 By 1 While Queued() > 0
   Parse Pull NewRecord
   If Queued() = 0 Then Do /* last record detected! */
      LastChar = Right( NewRecord, 1 )
      If LastChar = '1E'x Then /* remove '1E'x before appending '1D'x */
         NewRecord = Left( NewRecord, Length(NewRecord) - 1 )
      NewRecord = NewRecord || '1D'x     /* append to the last record only */
   End
   Push NewRecord
   "EXECIO 1 DISKW OUTDD"
End iRec
"EXECIO 0 DISKW OUTDD (FINIS"
"DELSTACK"
Return 0
 
Javas and Pythons come and go, but JCL and SORT stay forever.

These users thanked the author sergeyken for the post:
golemis (Wed Feb 19, 2020 3:39 am)
User avatar
sergeyken
 
Posts: 408
Joined: Wed Jul 24, 2019 10:12 pm
Has thanked: 6 times
Been thanked: 40 times

Re: Update Last Char in last Record of a Dataset

Postby golemis » Wed Feb 19, 2020 3:40 am

Thanks Sergey,
I have already done it with REXX. I only wanted to avoid REXX, as the rest of the gang here do not feel comfortable with REXX. That's why I am trying to use as much SORT as possible.
Thanks for confirming that there is no easy way to do it with SORT alone, without spliting the dataset with SUBSET.
I really appreciate your time,
Thanks again
GG
golemis
 
Posts: 34
Joined: Wed Apr 04, 2018 8:13 pm
Location: London, UK
Has thanked: 10 times
Been thanked: 0 time

Re: Update Last Char in last Record of a Dataset

Postby sergeyken » Thu Feb 20, 2020 6:18 pm

The example above is a classic way of any sequential dataset processing.

In this particular case, when we know for sure that only one single record needs to be processed, the REXX code can be significantly simplified:

/* REXX */
FIXUNIX:
"NEWSTACK"
"EXECIO * DISKR INDD (FINIS" /* read the whole dataset into program stack */
TotalRecords = Queued()
If TotalRecords > 0 Then Do /* non-empty input? */
   "EXECIO" (TotalRecords - 1) "DISKW OUTDD (OPEN" /* write back all except the last record */

   Parse Pull LastRecord
   LastChar = Right( LastRecord, 1 )

   If LastChar = '1E'x Then /* remove '1E'x before appending '1D'x */
      LastRecord = Left( LastRecord, Length(LastRecord) - 1 )

   LastRecord = LastRecord || '1D'x     /* append to the last record only */
   Push LastRecord
   "EXECIO 1 DISKW OUTDD" /* re-write last record */
End
"EXECIO 0 DISKW OUTDD (FINIS" /* close the output, either empty or not */
"DELSTACK"

Return 0
Javas and Pythons come and go, but JCL and SORT stay forever.
User avatar
sergeyken
 
Posts: 408
Joined: Wed Jul 24, 2019 10:12 pm
Has thanked: 6 times
Been thanked: 40 times

Re: Update Last Char in last Record of a Dataset

Postby prino » Fri Feb 21, 2020 1:39 am

Add a sequence number in SORT, sort descending, change the first record, resort ascending stripping off the sequence number. Just about as (in)efficient as a REXX execio of the entire dataset of half-a-million 80 byte records.
Robert AH Prins
robert.ah.prins @ the.17+Gb.Google thingy

These users thanked the author prino for the post:
golemis (Fri Feb 21, 2020 9:38 am)
User avatar
prino
 
Posts: 635
Joined: Wed Mar 11, 2009 12:22 am
Location: Vilnius, Lithuania
Has thanked: 3 times
Been thanked: 28 times

Re: Update Last Char in last Record of a Dataset

Postby sergeyken » Fri Feb 21, 2020 5:28 pm

prino wrote:Add a sequence number in SORT, sort descending, change the first record, resort ascending stripping off the sequence number. Just about as (in)efficient as a REXX execio of the entire dataset of half-a-million 80 byte records.


Any person who has ever dealt with millions-record datasets would not ask such questions at the Beginners Forum.
Javas and Pythons come and go, but JCL and SORT stay forever.
User avatar
sergeyken
 
Posts: 408
Joined: Wed Jul 24, 2019 10:12 pm
Has thanked: 6 times
Been thanked: 40 times

Re: Update Last Char in last Record of a Dataset

Postby NicC » Fri Feb 21, 2020 6:14 pm

And yet it was stated in the original post that the dataset held more than .5 million records so Prino's point is valid and I, as an 'expert' ie >40 years experience, would post my sort queries in this forum because I am not an expert on sort beyond the basics.
The problem I have is that people can explain things quickly but I can only comprehend slowly.
Regards
Nic
NicC
Global moderator
 
Posts: 3025
Joined: Sun Jul 04, 2010 12:13 am
Location: Pushing up the daisies (almost)
Has thanked: 4 times
Been thanked: 136 times

Re: Update Last Char in last Record of a Dataset

Postby sergeyken » Fri Feb 21, 2020 9:40 pm

NicC wrote:And yet it was stated in the original post that the dataset held more than .5 million records so Prino's point is valid and I, as an 'expert' ie >40 years experience, would post my sort queries in this forum because I am not an expert on sort beyond the basics.


Prino's solution:
1) re-sort the numbered huge input in reverse order, and
2) update its first record, and
3) re-sort it back to the original order
- seems to be even more suicidal than simple REXX-EXECIO...

If needed, SORT tools can be used like this.
At least - only two sequential scans, without re-ordering...

//*============================================================
//* MODIFY LAST RECORD ONLY                                    
//*============================================================
//SORTGRP  EXEC PGM=ICETOOL                                    
//*                                                            
//SYMNAMES DD DCB=(RECFM=FB,LRECL=80),                        
//            SPACE=(TRK,1)                                    
//*                                                            
//TOOLMSG  DD  SYSOUT=*                                        
//DFSMSG   DD  SYSOUT=*                                        
//*                                                            
//SORTIN   DD  *                                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
no need to change          --->$                              
NEED TO CHANGE THIS RECORD --->$                              
//*                                                            
//*------------------------------------------------------------
//TOOLIN   DD  *                                              
  COPY FROM(SORTIN) TO(SYMNAMES)    USING(S001)                
  COPY FROM(SORTIN) TO(SORTOUT)     USING(S002)                
//*                                                            
//*--------------------------------------------------------------
//S001CNTL DD  *                                                
 OUTFIL FNAMES=(COUNT@,SYMNAMES),                                
        REMOVECC,NODETAIL,                                      
        TRAILER1=('$lastnum,',COUNT=(ZD,LENGTH=10),80:X)        
//*--------------------------------------------------------------
//S002CNTL DD  *                                                
 INREC BUILD=(1,80,SEQNUM,4,BI)                                  
 OUTREC IFTHEN=(WHEN=(81,4,BI,EQ,$lastnum),                      
                FINDREP=(INOUT=(X'1E',X'1D',                    
                                C'$',C'@')))                    
 OUTFIL BUILD=(1,80)                                            
//*                                                              
//*--------------------------------------------------------------
//COUNT@   DD  SYSOUT=*                                          
//SORTOUT  DD  SYSOUT=*                                          
//*                                                              
//*==============================================================
 


********************************* TOP OF DATA ******
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
no need to change          --->$                    
NEED TO CHANGE THIS RECORD --->@                    
******************************** BOTTOM OF DATA ****
 
Javas and Pythons come and go, but JCL and SORT stay forever.
User avatar
sergeyken
 
Posts: 408
Joined: Wed Jul 24, 2019 10:12 pm
Has thanked: 6 times
Been thanked: 40 times

Next

Return to DFSORT/ICETOOL/ICEGENER

 


  • Related topics
    Replies
    Views
    Last post