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.