ZZUtils
- ZZMATCH
ZZMATCH is an example of a Natural sequential match program.
This is a common 3GL structure, typically used to process a transaction
file against a master file.
ZZMATCH demonstrates a program design which maximizes ADABAS performance.
It is used to replace READ/FIND structures; the FIND is replaced with a
READ WORK.
In addition to performance improvement, ZZMATCH has the ability to determine
widows and orphans in a single pass. The READ/FIND construct requires
two passes to achieve this: READmaster/FINDtrans to determine widows; READtrans/FINDmaster
to determine orphans.
ZZMATCH is in the source module section of ZZUtils,
a collection of Natural utilities. Look for more information in my
Natural Tips & Techniques section - Tip
5.
Sequential Match Program for ADABAS
************************************************************************
* Program ID : ZZMATCH
* System :
* Subsystem :
* Function : Sequential Match
* Author : R. Zbrog
* Date written : 02/18/89
* Maps
: None
* Program maintenance log:
************************************************************************
* Date || Name || Summary
of Changes
************************************************************************
* 09/23/94|| R. Zbrog || Nat 2.2.5 & new NAVIGATION view
* 09/29/93|| R. Zbrog || Comments requesting custom code.
* 12/16/92|| R. Zbrog || Trace
************************************************************************
* Sample sequential-match program.
*
* Matches an ADABAS file and a work file -
the ADABAS file MUST be
* processed as the outer loop. Two sequential
files may be matched by
* replacing the ADABAS READ loop with a READ WORK loop
(although no
* starting value may be specified for the READ WORK
loop). Two ADABAS
* files may not be matched; one of them must be converted
to a work
* file (ie the inner loop MUST process a WORK file).
*
* This example detects record matches, extra ADABAS
records, and extra
* WORK records. Non-unique keys are handled on
both files.
*
* The WORK file must be in the same sequence as the
(super)descriptor
* by which the ADABAS file is read.
*
* The program uses 'standard' logic for a master file
updated by a
* transaction file. The views are called MSTR
(ADABAS) and TRAN
* (WORK). It assumes a MSTR:TRANS ratio of 1:n.
The program works
* fine with a ratio of 1:1, but should be optimized
if this is the
* case. (Indeed, the files may not be true master
and transaction
* files; it is the one-to-many ratio that defines which
file will be
* treated as master and which will be treated as transaction.)
*
* This program may be a good ADABAS Prefetch candidate.
*
* When customizing this program, review all comments
for coding
* suggestions. Lines marked with '<<<<<'
contain mandatory changes.
* Use 'optional' code if it is appropriate. Remove
optional code if
* it is not needed; this will improve performance.
*
*
DEFINE DATA LOCAL
1 MSTR VIEW NAVIGATION
2 SYS-CODE
2 PRFL-NAME
2 CRNT-SCRN-NAME
2 PRGM-FSTPTH-FLAG
2 OPTIONS(7)
2 REDEFINE OPTIONS
3 OPTN-GRUP(32)
4 FILLER 12X
4 OPTN-SLCTN-DESC(A35)
4 FILLER 5X
*
*
1 #TRAN
2 SYS-CODE(A2)
2 PRFL-NAME(A8)
2 CRNT-SCRN-NAME(A4)
2 PRGM-FSTPTH-FLAG(A1)
2 OPTN-SLCTN-DESC(A35)
*
*
1 #START
/* Optional FROM processing
2 SYS-CODE(A2)
INIT <' '>
2 PRFL-NAME(A8)
INIT <' '>
2 CRNT-SCRN-NAME(A4)
INIT <' '>
2 PRGM-FSTPTH-FLAG(A1) INIT <'
'>
1 REDEFINE #START
2 #START-KEY(A15)
*
1 #END
/* Optional THRU processing
2 SYS-CODE(A2)
INIT <'99'>
2 PRFL-NAME(A8)
INIT <'99999999'>
2 CRNT-SCRN-NAME(A4)
INIT <'9999'>
2 PRGM-FSTPTH-FLAG(A1) INIT <'9'>
1 REDEFINE #END
2 #END-KEY(A15)
*
1 #MKEY
/* Build key from non-contiguous fields
2 SYS-CODE(A2)
2 PRFL-NAME(A8)
2 CRNT-SCRN-NAME(A4)
2 PRGM-FSTPTH-FLAG(A1)
1 REDEFINE #MKEY
2 #MSTR-KEY(A15)
*
1 #TKEY
/* Build key from non-contiguous fields
2 SYS-CODE(A2)
2 PRFL-NAME(A8)
2 CRNT-SCRN-NAME(A4)
2 PRGM-FSTPTH-FLAG(A1)
1 REDEFINE #TKEY
2 #TRAN-KEY(A15)
*
*
1 #N
/* Counters
2 CNTM(P7)
2 EXTM(P7)
2 CNTT(P7)
2 EXTT(P7)
2 MCHT(P7)
*
1 #LOGICALS
2 #MSTR-MATCHED(L)
2 #TRAN-NEEDED(L)
INIT<TRUE>
2 #EOF(L)
INIT<FALSE>
2 #TRACE-ALL(L)
INIT<FALSE>
2 #TRACE-MSTR(L)
INIT<FALSE>
2 #TRACE-TRAN(L)
INIT<FALSE>
2 #TRACE-MISC(L)
INIT<FALSE>
*
1 #MISC
2 #DATE(A8)
INIT<*DATU> /* Constant for report
2 #TIME(A5)
INIT<*TIME> /* Constant for report
END-DEFINE
*
FORMAT(01) PS=60 LS=132
*/
*
READ MSTR BY SYS-PRFL-SCRN-SPDE
/* Optional: READ WORK 1
FROM #START-KEY
/* Optional
ASSIGN #MKEY.SYS-CODE
= MSTR.SYS-CODE
/* Build a
ASSIGN #MKEY.PRFL-NAME
= MSTR.PRFL-NAME
/* contiguous
ASSIGN #MKEY.CRNT-SCRN-NAME = MSTR.CRNT-SCRN-NAME
/* key
ASSIGN #MKEY.PRGM-FSTPTH-FLAG = MSTR.PRGM-FSTPTH-FLAG
/* (optional)
IF #MSTR-KEY > #END-KEY
/* Optional 'thru'
THEN
ESCAPE BOTTOM
END-IF
ADD 1 TO #N.CNTM
ASSIGN #MSTR-MATCHED = FALSE
/* Not yet matched
*
*
RPT.
REPEAT
IF #TRAN-NEEDED
THEN
READ WORK 1 ONCE #TRAN
/* Use WORK 2 if outer loop WORK
AT END OF FILE
ASSIGN #EOF = TRUE
END-ENDFILE
IF #EOF
THEN
MOVE ALL H'FF' TO #TRAN-KEY
ASSIGN #TRAN-NEEDED = FALSE
ELSE
/* Build a contiguous key
ASSIGN #TKEY.SYS-CODE =
#TRAN.SYS-CODE
ASSIGN #TKEY.PRFL-NAME = #TRAN.PRFL-NAME
ASSIGN #TKEY.CRNT-SCRN-NAME = #TRAN.CRNT-SCRN-NAME
ASSIGN #TKEY.PRGM-FSTPTH-FLAG = #TRAN.PRGM-FSTPTH-FLAG
ADD 1 TO #N.CNTT
END-IF
END-IF
*
DECIDE FOR FIRST CONDITION
WHEN #MSTR-KEY < #TRAN-KEY
/* Must get next master
IF
NOT #MSTR-MATCHED /* Previously matched
THEN
/* Process an unmatched master
IF #TRACE-ALL
OR #TRACE-MSTR
THEN
WRITE(01)
2T MSTR.SYS-CODE
7T MSTR.PRFL-NAME
17T MSTR.CRNT-SCRN-NAME
25T MSTR.PRGM-FSTPTH-FLAG
29T 'Extra Master'
56T #N.CNTM(EM=Z,ZZZ,ZZ9)
78T MSTR.OPTN-SLCTN-DESC(1)
END-IF
*
* <<<<<
Code 'widow' logic here.
*
ADD 1 TO #N.EXTM
END-IF
ASSIGN
#TRAN-NEEDED = FALSE /* Apply to next master
ESCAPE
BOTTOM(RPT.) /* Process
next master
WHEN #MSTR-KEY = #TRAN-KEY
/* Process a match
IF
#TRACE-ALL
OR #TRACE-MSTR
OR #TRACE-TRAN
THEN
WRITE(01)
2T MSTR.SYS-CODE
7T MSTR.PRFL-NAME
17T MSTR.CRNT-SCRN-NAME
25T MSTR.PRGM-FSTPTH-FLAG
29T 'Matched MSTR/TRAN'
56T #N.CNTM(EM=Z,ZZZ,ZZ9)
67T #N.CNTT(EM=Z,ZZZ,ZZ9)
78T #TRAN.OPTN-SLCTN-DESC
END-IF
ADD
1 TO #N.MCHT
*
* <<<<< Code 'match' logic here.
*
ASSIGN
#MSTR-MATCHED = TRUE
ASSIGN
#TRAN-NEEDED = TRUE /* Try next transaction
* >>> ESCAPE BOTTOM(RPT.)
/* Next master; force 1:1 ratio
WHEN #MSTR-KEY > #TRAN-KEY
/* Process an unmatched tran
IF
#TRACE-ALL
OR #TRACE-TRAN
THEN
WRITE(01)
2T #TRAN.SYS-CODE
7T #TRAN.PRFL-NAME
17T #TRAN.CRNT-SCRN-NAME
25T #TRAN.PRGM-FSTPTH-FLAG
29T 'Extra Transaction'
67T #N.CNTT(EM=Z,ZZZ,ZZ9)
78T #TRAN.OPTN-SLCTN-DESC
END-IF
ADD
1 TO #N.EXTT
PERFORM
ORPHAN
ASSIGN
#TRAN-NEEDED = TRUE /* Try next transaction
WHEN NONE
IGNORE
END-DECIDE
END-REPEAT
END-READ
*
IF #TRAN-NEEDED
/* No waiting transaction
OR #EOF
/* Transaction end of file
THEN
IGNORE
ELSE
IF #TRACE-ALL
OR #TRACE-TRAN
THEN
WRITE(01)
2T #TRAN.SYS-CODE
7T #TRAN.PRFL-NAME
17T #TRAN.CRNT-SCRN-NAME
25T #TRAN.PRGM-FSTPTH-FLAG
29T 'Trailing TRAN'
67T #N.CNTT(EM=Z,ZZZ,ZZ9)
78T #TRAN.OPTN-SLCTN-DESC
END-IF
ADD 1 TO #N.EXTT
PERFORM ORPHAN
END-IF
*
REPEAT WHILE NOT #EOF
/* Process extra TRAN records
READ WORK 1 ONCE #TRAN
AT END OF FILE
ESCAPE BOTTOM
END-ENDFILE
ADD 1 TO #N.CNTT
IF #TRACE-ALL
OR #TRACE-TRAN
THEN
WRITE(01)
2T #TRAN.SYS-CODE
7T #TRAN.PRFL-NAME
17T #TRAN.CRNT-SCRN-NAME
25T #TRAN.PRGM-FSTPTH-FLAG
29T 'Extra TRAN > Last MSTR'
67T #N.CNTT(EM=Z,ZZZ,ZZ9)
78T #TRAN.OPTN-SLCTN-DESC
END-IF
ADD 1 TO #N.EXTT
PERFORM ORPHAN
END-REPEAT
*
*
NEWPAGE(01)
WRITE(01)
// #N.CNTM(EM=Z,ZZZ,ZZ9) 'Master
Records Read'
// #N.CNTT(EM=Z,ZZZ,ZZ9) 'Transaction
Records Read'
//// #N.EXTM(EM=Z,ZZZ,ZZ9) 'Unmatched
Masters'
// #N.EXTT(EM=Z,ZZZ,ZZ9) 'Unmatched
Transactions'
//// #N.MCHT(EM=Z,ZZZ,ZZ9) 'Matched
Transactions'
*
*
WRITE(01) TITLE LEFT
'ZZMATCH'
10T 'Natural Utilities'
120T 'Page:' *PAGE-NUMBER(01)(EM=ZZ,ZZ9)
/ 10T 'Sample Sequential Match Program'
118T #DATE
#TIME
// 'Sys
Map Fast'
56T ' Master
Trans'
/ 'Code
Profile Name Path Message'
56T ' Record
Record Description'
/
*
*
DEFINE SUBROUTINE ORPHAN
*
* Code 'orphan' logic here.
<<<<<
*
ESCAPE ROUTINE
/* Replace with 'orphan' logic
END-SUBROUTINE
END
Return to top.
Return to Ralph G. Zbrog's home page.
Last updated April 25, 1998, by Ralph
G. Zbrog.