dbzTHEdinosauer Supermod
Joined: 20 Oct 2006 Posts: 1411 Topics: 26 Location: germany
|
Posted: Mon Jul 16, 2007 1:52 pm Post subject: Special case RESTART Procedure |
|
|
dbz made some changes to the sort cards 18-07-07 19:08
The syntax is not yet correct for the SORT STEPS, though the concept is achievable. I will work on the SORT cards and modify this complete post when finished. dbz
Here is another approach, based on the following assumptions:- there is an ORDER BY clause in your DEFINE CURSOR statement
- there is enough information in your output record to generate a reliable WHERE clause for the DEFINE CURSOR statement
- you are only FETCHing the DB2 table and not UPDATEing
- DFSORT is available in your shop
- your program needs one additional additional FD
- INPUT
- record length = existing output record length plus 15
- you need to write some logic for the new file. See STEP0050 explanation below.
- OPEN your OUTPUT file EXTEND
- the step that invokes your program requires an additional DD statement for the new input file
- modify the output file disposition parms to MOD,KEEP,KEEP
The new file will be called HLQ.MYRSTRT, DD Reference name (and assign clause) = MYRSTRT and will only be a one record file.
For purposes of this discussion, the output file of your program will be HLQ.MYOUTPUT. DD Reference name = MYOUTPUT
STEP0010 will create the MYOUTPUT file and DELETE the MYRSTRT file (actually you could use a temp file for MYRSTRT.
STEP0020 will count the MYOUTPUT file. First time thru, MYOUTPUT is empty and we will jump to STEP0040
STEP0030 will only be executed if this is indeed a restart. MYOUTPUT is not empty, we skip to the last record, and append the record count of MYOUTPUT to the last 15 char of the record. Based on COND CODEs, STEP0040 will be skipped and we will jump to STEP0050
STEP0040 will only be executed the first time - MYOUTPUT IS EMPTY, generate a record or just allocate an empty file and let the pgm handle an empty MYRSTRT as containing a zero count.
STEP0050 is the PGM. READS the MYRSTRT file, and plugs the host variables in the WHERE clause of the DEFINE CURSOR so that the first FETCH returns the next row to be processed.
STEP0060 will only be executed if STEP0050 does NOT ABEND. It will rename the MYOUTPUT file, so that the next time this JOB runs, MYOUTPUT will be empty and the CURSOR will be OPENed at the start.
There is a possibility (lol) that the SORT parms needs a little tweaking.
The JOB would be Code: |
//*
//* CREATE PGM OUTPUT FILE
//* DELETE RESTART FILE
//*
//STEP0010 EXEC PGM=IEFBR14
//MYOUTPUT DD DSN=HLQ.MYOUTPUT,
// DISP=(MOD,CATLG,CATLG),
// DCB=<whatever your dcb parms are>,
// SPACE=(TRK,(?,?))
//MYRSTRT DD DSN=HLQ.MYRSTRT
// DISP=(MOD,DELETE,DELETE),
// SPACE=(TRK,(1,1))
//*
//* COUNT OUTPUT FILE
//* GENERATE TEMP FILE TO HOLD SYMBOLIC COUNTER W/COUNT OF RECORDS - 1
//*
//STEP0020 EXEC PGM=ICEMAN
//SYSOUT DD SYSOUT=
//SORTIN DD DSN=HLQ.MYOUTPUT
//SORTOUT DD DSN=&T1,DISP=(,PASS),SPACE=(TRK,(1,1),RLSE)
//SYSIN DD
COPY COUNT FROM(SORTIN) EMPTY
OUTFIL NODETAIL,REMOVECC,
TRAILER1=(01:C'COUNTER,',
09:COUNT-1)
/*
//*
//* &T1 contains a SYMBOLIC COUNTER with a value of num-records IF MYOUTPUT NOTEMPTY
//*
//* NOW, OUTPUT THE LAST RECORD IN THE 'OUTPUT' FILE AS A TRAILER RECORD
//* AND APPEND NUMBER OF RECORDS.
//*
//STEP0030 EXEC PGM=SORT,COND=(STEP0020,GT,0)
//SYMNAMES DD DSN=&T1,DISP=OLD
//SYSOUT DD SYSOUT=*
//SORTIN DD DNS=HLQ.MYOUTPUT,
// DISP=SHR
//SORTOUT DD DSN=HLQ.MYRSTRT,
// DISP=(MOD,CATLG,CATLG),
// DCB=<whatever your dcb parms for MYOUTPUT + 15>,
// SPACE=(TRK,(1,1))
//SYSIN DD *
COPY STARTAFT=COUNTER-1
OUTREC OVERLAY=(<ln of myoutput + 1:COUNTER+1=(M11,LENGTH=15))
/*
//*
//* IF MYOUTPUT IS EMPTY, THEN GENERATE A ZERO RESTART RECORD
//*
//STEP0040 EXEC PGM=SORT,COND=(STEP0020,EQ,0)
//SYSOUT DD SYSOUT=*
//SORTIN DD DUMMY
//SORTOUT DD DSN=HLQ.MYRSTRT,
// DISP=(MOD,CATLG,CATLG),
// DCB=<whatever your dcb parms for MYOUTPUT + 15>,
// SPACE=(TRK,(1,1))
//SYSIN DD *
COPY COUNT FROM(SORTIN) HIGHER(1)
OUTFIL NODETAIL,REMOVECC,
TRAILER1=(<ln of myoutput + 1:COUNT=(M11,LENGTH=15)
/*
//*
//*
//* HLQ.MYRSTRT IS A 1 RECORD DATASET WHICH CONTAINS:
//* POS 1 A COPY OF THE LAST RECORD OUTPUT
//* <LENGTH OF HLQ.MYOUTPUT + 1> NUMBER OF RECORDS IN OUTPUT.
//*
//STEP0050 EXEC PGM=YOURPGM
//MYRSTRT DD DSN=HLQ.MYRSTRT,
// DISP=SHR
//MYOUTPUT DD DSN=HLQ.MYOUTPUT,
// DISP=(MOD,KEEP,KEEP)
// <the rest of your dd statments....>
//*
//*
//* STEP0060 WILL RENAME HLQ.MYOUTPUT TO WHATEVER NAME IS NEEDS TO BE FOR
//* THE NEXT PRODUCTION JOB.
//* IF STEP0050 ABENDS, THEN STEP0060 WILL NEVER EXECUTE AND THE HLQ.MYOUTPUT
//* REMAINS UNTIL A SUCCESSFUL END OF STEP0050
//STEP0060 EXEC PGM=?
|
Another way would have been to Father-Son the MYOUTPUT file in the PGM, but
SORT only reads the file (twice) and only outputs one record.
Enough buffering and I bet that 2 SORTs only reading
would be faster than
a READ and WRITE within the PGM, especially if there are a lot of records.
sivafdms,
you had better be issuing periodic COMMITs!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! _________________ Dick Brenholtz
American living in Varel, Germany |
|