Search code examples
jcldfsort

Sort unmatched records using joinkeys


I have two GDG files (-1 & 0 version). Using these two files a flat file needs to be generated which will have Insert records(records which are not in -1 version but are in +0 version), Delete records(records which are in -1 version but are not in +0 version) and Update records(records which are in both the versions but the +0 version might have changes in some of the fields). How can i get those update records? Can i do it using Joinkeys, if yes, How?

Note: The update can be anywhere from column 1 to the last column of the file(+0 version of the GDG)


Solution

  • It is a simple JOINKEYS:

      OPTION COPY 
      JOINKEYS F1=INA,FIELDS=(4,80),SORTED,NOSEQCK 
      JOINKEYS F2=INB,FIELDS=(4,80),SORTED,NOSEQCK 
      JOIN UNPAIRED 
      REFORMAT FIELDS=(F1:1,227,F2:1,227,?) 
    

    The OPTION COPY is for the Main Task, the bit which runs after the joined file is produced. SORT FIELDS=COPY is equivalent to OPTION COPY.

    The assumption is that your data is in key order already. If not, remove the SORTED,NOSEQCKs but bear in mind that you may get "spurious" matches, by equal keys not in the same position on the file relative to inserts and deletes.

    JOIN UPAIRED gives you matches and both types of mismatch. JOIN UNPAIRED,F1,F2 is equivalent.

    The REFORMAT statement defines the records on the joined file. You want all the data from both/either record, and you want to know whether there was a match, and if no match, which input file had the record. That is what the question-mark (?) is. It will contain 'B' (on both files), '1' (on F1, or the first physically present JOINKEYS, only) or '2' (on the other JOINKEYS file only).

    Then you need to output the data. I'll assume you want the data in separate places:

      OUTFIL FNAMES=INSERT,
             INCLUDE=(455,1,CH,EQ,C'1'),
             BUILD=(1,227)
      OUTFIL FNAMES=DELETE,
             INCLUDE=(455,1,CH,EQ,C'2'),
             BUILD=(228,227)
      OUTFIL FNAMES=CHANGE,
             INCLUDE=(455,1,CH,EQ,C'B',
                     AND,
                      1,227,CH,NE,228,227,CH),
             BUILD=(1,454)
      OUTFIL FNAMES=UNCHNGE,
             SAVE,
             BUILD=(1,227)
    

    INCLUDE= (or OMIT=) includes or omits the data from the "OUTFIL Group". OUTFILs "run" concurrently (as in the same record is presented to each in turn, then the next record, etc).

    FNAMES gives you the DDname to put in the JCL.

    For CHANGE, the INCLUDE is for the first record (known to match due to the test for 'B') not being equal to the second. It is not exactly clear what output you want here. Currently those are output as F2 appended to F1, and entire (twice the size) record written. You could also write the records in "pairs" (BUILD=(1,227,/,228,227)) or just one or the other of the records.

    SAVE is a thing which says "if this record hasn't appeared on any OUTFIL, output it here. It is certainly useful for testing, even if you don't want it in the final code.