Identity Resolution
- Identity Resolution 10.5
- All Products
Example 1: | Index Person Names with 5 byte binary keys using a databaseto- database method. |
Example 2: | Index Company Names with 8 byte character keys using a database-to-database method. |
Example 3: | Index Street addresses with 5 byte binary keys using a databaseto- sequential file method. |
Example 1: | Search for a person’s name and display the results in ranked order by the probability of match. Optionally uses a postal/zip code to refine the search results list. Uses 5-byte keys. |
Example 2: | Search for a company prior to adding it as a new customer. Displays the definite matches only, based on name and street address. If no match exists, store the new record on the customer db. Uses 8 byte keys. |
Example 3: | Read a file of new customer transactions and check if there is a suspicion that they already exist on the customer db. If so, print an exception report, otherwise add the new customer to the database. Uses 8 byte SSA-NAME3 keys. |
/*----------------------------------------------------------------------------*/ /* KEY-LOAD EXAMPLE 1 */ /* */ /* Purpose: Use SSA-NAME3 to index Person Names with 5 byte */ /* binary keys using a database-to-database method */ /* Description: Sequentially reads a customer database table. */ /* For each record the SSA-NAME3 NAMESET Service is */ /* called passing the person’s name. For each key in */ /* the keys stack returned by NAMESET, a row is */ /* inserted into the SSA-NAME3 Key database table */ /* along with the customer data that will be used for */ /* matching or displaying in a search. */ /* Pre-requisites: 1. Requires the PERSON Algorithm to be customized */ /* and generated as part of the SSA-NAME3 Service */ /* Group */ /* 2. Requires access to the executable SSA-NAME3 */ /* Service Group in the environment where the */ /* program is to run. */ /* 3. Requires the database table to be defined for */ /* the SSA-NAME3 Keys. */ /* */ /*----------------------------------------------------------------------------*/ /****** DATABASE DEFINITIONS ******/ CUSTOMER-TABLE/* customer db table */ CUST-ID CHAR(10) CUST-GIVEN-NAMES CHAR(30) CUST-FAMILY-NAME CHAR(20) CUST-ADDR-LINE1 CHAR(40) CUST-ADDR-LINE2 CHAR(40) CUST-CITY CHAR(20) CUST-STATE CHAR(3) CUST-POSTAL-CODE CHAR(8) CUST-COUNTRY CHAR(20) CUST-BIRTH-DATE CHAR(10) SSA-NAME3-TABLE/* SSA-NAME3 Key db table */ SSA-NAME3-CUST-KEY CHAR(5) CUST-ID CHAR(10) SSA-NAME3-CUST-NAME CHAR(50) SSA-NAME3-CUST-STREET CHAR(80) SSA-NAME3-CUST-LOCALITY CHAR(45) CUST-POSTAL-CODE CHAR(8) CUST-BIRTH-DATE CHAR(10) /****** VARIABLE DEFINITIONS ******/ /*** NAMESET PARAMETERS ***/ SSA-NAME3-NAMESET-SERVICE CHAR(8) VALUE ’NAMESETP’ /* the NAMESET Service name */ /* must be defined in the */ /* Algorithm Definition */ SSA-NAME3-NAMESET-FUNCTION CHAR(32) VALUE ’*NOSTAB*’ SSA-NAME3-NAME-INCHAR(50) /* SSA-NAME3-NAME-IN & */ /* SSA-NAME3-NAME-CLEAN */ /* must be the same */ /* length as specified */ /* in the Algorithm */ SSA-NAME3-NAME-CLEAN CHAR(50) /* NAME-LENGTH parameter. */ SSA-NAME3-RESPONSE-CODE CHAR(20) REDEFINE SSA-NAME3-RESPONSE-CODE SSA-NAME3-ERROR-NUMBER CHAR(2) SSA-NAME3-ERROR-REASON CHAR(2) SSA-NAME3-ERROR-MODULE CHAR(2) SSA-NAME3-ERROR-SEVERITY CHAR(1) SSA-NAME3-ERROR-UNUSED CHAR(3) SSA-NAME3-SECONDARY-RC CHAR(10) SSA-NAME3-WORDS-STACK /* SSA-NAME3-WORDS-STACK must be */ SSA-NAME3-WORDS-COUNT NUM(2) /* large enough to cater for */ SSA-NAME3-WORDS OCCURS 8 TIMES /* the number of entries */ SSA-NAME3-WORD CHAR(24)/* defined in the Algorithm */ SSA-NAME3-WORD-TYPE CHAR(2) /* WORDS-STACK-SIZE parameter */ SSA-NAME3-WORD-CATEGORY CHAR(2) SSA-NAME3-ORIGINAL-INIT CHAR(1) FILLER CHAR(3) SSA-NAME3-KEYS-STACK /* SSA-NAME3-KEYS-STACK must be */ SSA-NAME3-KEYS-COUNT NUM(2) /* large enough to cater for */ SSA-NAME3-KEYS OCCURS 20 TIMES /* the number of entries */ SSA-NAME3-KEY CHAR(5) /* defined in the Alg */ SSA-NAME3-KEY-TYPE CHAR(2) /* KEYS-STACK-SIZE param */ SSA-NAME3-SEARCH-TABLE /* SSA-NAME3-SEARCH-TABLE */ SSA-NAME3-PREFERRED-KEY CHAR(5) /* must be large enough to */ SSA-NAME3-SEARCH-RANGES OCCURS 21 TIMES /* cater for the number of */ SSA-NAME3-KEY-FROM CHAR(5) /* entries defined in the */ SSA-NAME3-KEY-TO CHAR(5) /* Algorithm */ SSA-NAME3-RANGE-DEPTH CHAR(2) /* SEARCH-TABLE-SIZE */ SSA-NAME3-RANGE-SCALE CHAR(2) /* parameter */ SSA-NAME3-RANGE-CONTENTS CHAR(2) SSA-NAME3-RANGE-KEY-TYPE CHAR(2) SSA-NAME3-RANGE-TYPE CHAR(1) SSA-NAME3-RANGE-SEQUENCE CHAR(2) FILLER CHAR(11) SSA-NAME3-CATEGORIES CHAR(20) SSA-NAME3-WORK-AREA CHAR(99999) /* to check if the */ /* SSA-NAME3-WORK-AREA */ /* is large enough, run a */ REDEFINE SSA-NAME3-WORK-AREA /* Testbed NAMESET & MATCH */ SSA-NAME3-WORK-FIRST CHAR(42) /* Call and check the value */ SSA-NAME3-EXTENDED-RC CHAR(20) SSA-NAME3-DUMMY CHAR(1) /******* OTHER VARIABLES *****/ SSA-NAME3-KEYS-STACK-I NUM(2) /****** PROGRAM LOGIC ******/ /* ------------------------- */ /* initialize SSA parameters */ /* ------------------------- */ INITIALIZE SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES, SSA-NAME3-WORK-AREA. /* ------------------------------------------------ */ /* open cursor for sequential read of customer file */ /* ------------------------------------------------ */ DEFINE CUST-SEQUENTIAL-VIEW CURSOR SELECT CUST-ID, CUST-GIVEN-NAMES, CUST-FAMILY-NAME, CUST-ADDR-LINE1, CUST-ADDR-LINE2,CUST-CITY, CUST-STATE, CUST-POSTAL-CODE, CUST-COUNTRY, CUST-BIRTH-DATE FROM CUSTOMER-TABLE END-DEFINE OPEN CUST-SEQUENTIAL-VIEW /* -------------------------------------------------------------------- */ /* Read each row from the customer table and Call the NAMESET Service. */ /* For each key returned in the SSA keys stack, insert a record into */ /* the SSA Key Table */ /* -------------------------------------------------------------------- */ WHILE NOT END-OF-CURSOR FETCH CUST-SEQUENTIAL-VIEW IF END-OF-CURSOR BREAK END-IF STRING CUSTOMER-TABLE.CUST-GIVEN-NAMES CUSTOMER-TABLE.CUST-FAMILY-NAME INTO SSA-NAME3-NAME-IN MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-NAMESET-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAMESET-FUNCTION, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) IF SSA-NAME3-ERROR-NUMBER NOT = ’00’ IF SSA-NAME3-ERROR-NUMBER >= ’90’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY >= ’2’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY = ’1’ PRINT "SSA WARNING: " SSA-NAME3-RESPONSE-CODE END-IF END-IF /* ---------------------------------------- */ /* move the customer data to the ssa record */ /* ---------------------------------------- */ MOVE SSA-NAME3-NAME-IN TO SSA-NAME3-TABLE.SSA-NAME3-CUST-NAME MOVE CUSTOMER-TABLE.CUST-ID TO SSA-NAME3-TABLE.CUST-ID STRING CUSTOMER-TABLE.CUST-ADDR-LINE1 CUSTOMER-TABLE.CUST-ADDR-LINE2 INTO SSA-NAME3-TABLE.SSA-NAME3-CUST-STREET STRING CUSTOMER-TABLE.CUST-CITY CUSTOMER-TABLE.CUST-STATE CUSTOMER-TABLE.CUST-COUNTRY INTO SSA-NAME3-TABLE.SSA-NAME3-CUST-LOCALITY MOVE CUSTOMER-TABLE.CUST-POSTAL-CODE TO SSA-NAME3-TABLE.CUST-POSTAL-CODE MOVE CUSTOMER-TABLE.CUST-BIRTH-DATE TO SSA-NAME3-TABLE.CUST-BIRTH-DATE /* ---------------------------------------- */ /* move each SSA key to the SSA record and */ /* insert to the SSA Table */ /* ---------------------------------------- */ MOVE 1 TO SSA-NAME3-KEYS-STACK-I WHILE SSA-NAME3-KEYS-STACK-I <= SSA-NAME3-KEYS-COUNT MOVE SSA-NAME3-KEY (SSA-NAME3-KEYS-STACK-I) TO SSA-NAME3-CUST-KEY INSERT INTO SSA-NAME3-TABLE SSA-NAME3-CUST-KEY, CUST-ID, SSA-NAME3-CUST-NAME, SSA-NAME3-CUST-STREET, SSA-NAME3-CUST-LOCALITY, CUST-POSTAL-CODE, CUST-BIRTH-DATE. ADD 1 TO SSA-NAME3-KEYS-STACK-I END-WHILE COMMIT END-WHILE CLOSE CUST-SEQUENTIAL-VIEW STOP SSA-NAME3-ERROR-ABORT PRINT "SSA ERROR: " SSA-NAME3-RESPONSE-CODE ABORT /*----------------------------------------------------------------------------*/ /* KEY-LOAD EXAMPLE 2 */ /* */ /* Purpose: Use SSA-NAME3 to index Company Names with 8 byte */ /* character keys using a database-to-database method. */ /* Description: Sequentially reads a customer database table. */ /* For each record the NAMESET Service is called */ /* passing the customer name. For each key in the */ /* keys stack returned by NAMESET, a row is inserted */ /* into the SSA Key database table along with the */ /* customer data that will be used for matching or */ /* displaying in a search. */ /* Pre-requisites: 1. Requires the COMPANY Algorithm to be customized */ /* and generated as part of the SSA Service Group */ /* 2. Requires access to the executable SSA Service */ /* Group in the environment where the program is */ /* to run. */ /* 3. Requires the database table to be defined for */ /* the SSA Keys. */ /* */ /*----------------------------------------------------------------------------*/ /****** DATABASE DEFINITIONS ******/ CUSTOMER-TABLE /* customer db table */ CUST-ID CHAR(10) CUST-COMPANY-NAME CHAR(100) CUST-ADDR-LINE1 CHAR(40) CUST-ADDR-LINE2 CHAR(40) CUST-CITY CHAR(20) CUST-STATE CHAR(3) CUST-POSTAL-CODE CHAR(8) CUST-COUNTRY CHAR(20) SSA-NAME3-TABLE /* SSA-NAME3 Key db table */ SSA-NAME3-CUST-KEY CHAR(8) CUST-ID CHAR(10) SSA-NAME3-CUST-NAME CHAR(100) SSA-NAME3-CUST-STREET CHAR(80) SSA-NAME3-CUST-LOCALITY CHAR(45) CUST-POSTAL-CODE CHAR(8) /****** VARIABLE DEFINITIONS ******/ /*** SSA NAMESET PARAMETERS ***/ SSA-NAME3-NAMESET-SERVICE CHAR(8) VALUE ’NAMESETC’ /* the NAMESET Service name */ /* must be defined in the */ /* Algorithm Definition */ SSA-NAME3-NAMESET-FUNCTION CHAR(32) VALUE ’*NOSTAB*’ SSA-NAME3-NAME-IN CHAR(100) /* SSA-NAME3-NAME-IN & */ /* SSA-NAME3-NAME-CLEAN must */ /* be the same length as */ /* specified in the Alg */ SSA-NAME3-NAME-CLEAN CHAR(100) /* NAME-LENGTH parameter. */ SSA-NAME3-RESPONSE-CODE CHAR(20) REDEFINE SSA-NAME3-RESPONSE-CODE SSA-NAME3-ERROR-NUMBER CHAR(2) SSA-NAME3-ERROR-REASON CHAR(2) SSA-NAME3-ERROR-MODULE CHAR(2) SSA-NAME3-ERROR-SEVERITY CHAR(1) SSA-NAME3-ERROR-UNUSED CHAR(3) SSA-NAME3-SECONDARY-RC CHAR(10) SSA-NAME3-WORDS-STACK /* SSA-NAME3-WORDS-STACK must be */ SSA-NAME3-WORDS-COUNT NUM(2) /* large enough to cater for */ SSA-NAME3-WORDS OCCURS 8 TIMES /* the number of entries */ SSA-NAME3-WORD CHAR(24) /* defined in the Algorithm */ SSA-NAME3-WORD-TYPE CHAR(2) /* WORDS-STACK-SIZE parameter */ SSA-NAME3-WORD-CATEGORY CHAR(2) SSA-NAME3-ORIGINAL-INIT CHAR(1) FILLER CHAR(3) SSA-NAME3-KEYS-STACK /* SSA-NAME3-KEYS-STACK must */ SSA-NAME3-KEYS-COUNT NUM(2) /* be large enough to cater */ SSA-NAME3-KEYS OCCURS 20 TIMES /* for the number of entries */ SSA-NAME3-KEY CHAR(8) /* defined in the Algorithm */ SSA-NAME3-KEY-TYPE CHAR(2) /* KEYS-STACK-SIZE parameter */ SSA-NAME3-SEARCH-TABLE /* SSA-NAME3-SEARCH-TABLE */ SSA-NAME3-PREFERRED-KEY CHAR(8) /* must be large enough to */ SSA-NAME3-SEARCH-RANGES OCCURS 21 TIMES /* cater for the number of */ SSA-NAME3-KEY-FROM CHAR(8) /* entries defined in the */ SSA-NAME3-KEY-TO CHAR(8) /* Algorithm */ SSA-NAME3-RANGE-DEPTH CHAR(2) /* SEARCH-TABLE-SIZE parm */ SSA-NAME3-RANGE-SCALE CHAR(2) SSA-NAME3-RANGE-CONTENTS CHAR(2) SSA-NAME3-RANGE-KEY-TYPE CHAR(2) SSA-NAME3-RANGE-TYPE CHAR(1) SSA-NAME3-RANGE-SEQUENCE CHAR(2) FILLER CHAR(11) SSA-NAME3-CATEGORIES CHAR(20) SSA-NAME3-WORK-AREA CHAR(99999) /* to check if the */ /* SSA-NAME3-WORK-AREA is */ REDEFINE SSA-NAME3-WORK-AREA /* large enough, run a */ SSA-NAME3-WORK-FIRST CHAR(42) /* TestBed NAMESET & MATCH */ SSA-NAME3-EXTENDED-RC CHAR(20) /* Call and check the */ /* WSIZE= value. */ SSA-NAME3-DUMMY CHAR(1) /*** OTHER VARIABLES ***/ SSA-NAME3-KEYS-STACK-I NUM(2) /****** PROGRAM LOGIC ******/ /* ------------------------- */ /* initialize SSA parameters */ /* ------------------------- */ INITIALIZE SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES, SSA-NAME3-WORK-AREA. /* ------------------------------------------------ */ /* open cursor for sequential read of customer file */ /* ------------------------------------------------ */ DEFINE CUST-SEQUENTIAL-VIEW CURSOR SELECT CUST-ID, CUST-COMPANY-NAME, CUST-ADDR-LINE1, CUST-ADDR-LINE2, CUST-CITY, CUST-STATE, CUST-POSTAL-CODE, CUST-COUNTRY FROM CUSTOMER-TABLE END-DEFINE OPEN CUST-SEQUENTIAL-VIEW /* -------------------------------------------------------------------- */ /* Read each row from the customer table and Call the NAMESET Service. */ /* For each key returned in the SSA keys stack, insert a record into */ /* the SSA Key Table */ /* -------------------------------------------------------------------- */ WHILE NOT END-OF-CURSOR FETCH CUST-SEQUENTIAL-VIEW IF END-OF-CURSOR BREAK END-IF MOVE CUSTOMER-TABLE.CUST-COMPANY-NAME TO SSA-NAME3-NAME-IN MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-NAMESET-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAMESET-FUNCTION, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) IF SSA-NAME3-ERROR-NUMBER NOT = ’00’ IF SSA-NAME3-ERROR-NUMBER >= ’90’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY >= ’2’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY = ’1’ PRINT "SSA WARNING: " SSA-NAME3-RESPONSE-CODE END-IF END-IF /* ---------------------------------------- */ /* move the customer data to the ssa record */ /* ---------------------------------------- */ MOVE SSA-NAME3-NAME-IN TO SSA-NAME3-TABLE.SSA-NAME3-CUST-NAME MOVE CUSTOMER-TABLE.CUST-ID TO SSA-NAME3-TABLE.CUST-ID STRING CUSTOMER-TABLE.CUST-ADDR-LINE1 CUSTOMER-TABLE.CUST-ADDR-LINE2 INTO SSA-NAME3-TABLE.SSA-NAME3-CUST-STREET STRING CUSTOMER-TABLE.CUST-CITY CUSTOMER-TABLE.CUST-STATE CUSTOMER-TABLE.CUST-COUNTRY INTO SSA-NAME3-TABLE.SSA-NAME3-CUST-LOCALITY MOVE CUSTOMER-TABLE.CUST-POSTAL-CODE TO SSA-NAME3-TABLE.CUST-POSTAL-CODE /* ---------------------------------------- */ /* move each SSA key to the SSA record and */ /* insert to the SSA Table */ /* ---------------------------------------- */ MOVE 1 TO SSA-NAME3-KEYS-STACK-I WHILE SSA-NAME3-KEYS-STACK-I <= SSA-NAME3-KEYS-COUNT MOVE SSA-NAME3-KEY (SSA-NAME3-KEYS-STACK-I) TO SSA-NAME3-CUST-KEY INSERT INTO SSA-NAME3-TABLE SSA-NAME3-CUST-KEY, CUST-ID, SSA-NAME3-CUST-NAME, SSA-NAME3-CUST-STREET, SSA-NAME3-CUST-LOCALITY, CUST-POSTAL-CODE. ADD 1 TO SSA-NAME3-KEYS-STACK-I END-WHILE COMMIT END-WHILE CLOSE CUST-SEQUENTIAL-VIEW STOP SSA-NAME3-ERROR-ABORT PRINT "SSA ERROR: " SSA-NAME3-RESPONSE-CODE ABORT /*-------------------------------------------------------------------------- */ /* KEY-LOAD EXAMPLE 3 */ /* */ /* Purpose: Use SSA-NAME3 to index Street addresses with 5 */ /* byte binary keys using a database-to-sequential */ /* file method */ /* Description: Sequentially reads a customer database table. */ /* For each record the SSA NAMESET STREET Service is */ /* called passing the street address. For each key in */ /* the keys stack returned by NAMESET, a record, */ /* comprised of the SSA Key and the customer data */ /* that will be used for matching, is written to a */ /* a sequential file. This sequential file should */ /* be sorted by the SSA key and loaded into a */ /* database table. It could also be used as input to */ /* a batch sequential matching process. */ /* Pre-requisites: 1. Requires the STREET Algorithm to be customized */ /* and generated as part of the SSA Service Group */ /* 2. Requires access to the executable SSA Service */ /* Group in the environment where the program is */ /* to run. */ /* */ /*-------------------------------------------------------------------------- */ /****** DATABASE DEFINITIONS ******/ CUSTOMER-TABLE /* customer db table */ CUST-ID CHAR(10) CUST-GIVEN-NAMES CHAR(30) CUST-FAMILY-NAME CHAR(20) CUST-ADDR-LINE1 CHAR(40) CUST-ADDR-LINE2 CHAR(40) CUST-CITY CHAR(20) CUST-STATE CHAR(3) CUST-POSTAL-CODE CHAR(8) CUST-COUNTRY CHAR(20) CUST-BIRTH-DATE CHAR(10) /****** FILE DEFINITIONS ******/ SSA-NAME3-KEY-FILE /* SSA Key sequential file */ SSA-NAME3-CUST-KEY CHAR(5) CUST-ID CHAR(10) SSA-NAME3-CUST-NAME CHAR(50) SSA-NAME3-CUST-STREET CHAR(80) SSA-NAME3-CUST-LOCALITY CHAR(45) CUST-POSTAL-CODE CHAR(8) CUST-BIRTH-DATE CHAR(10) /****** VARIABLE DEFINITIONS ******/ /*** SSA NAMESET PARAMETERS ***/ SSA-NAME3-NAMESET-SERVICE CHAR(8) VALUE ’NAMESETS’ /* the NAMESET Service name */ /* must be defined in the */ /* Algorithm Definition */ SSA-NAME3-NAMESET-FUNCTION CHAR(32) VALUE ’*NOSTAB*’ SSA-NAME3-NAME-IN CHAR(80) /* SSA-NAME3-NAME-IN & */ /* SSA-NAME3-CLEAN must be */ /* the same length as */ /* specified in the Alg */ SSA-NAME3-NAME-CLEAN CHAR(80) /* NAME-LENGTH parameter. */ SSA-NAME3-RESPONSE-CODE CHAR(20) REDEFINE SSA-NAME3-RESPONSE-CODE SSA-NAME3-ERROR-NUMBER CHAR(2) SSA-NAME3-ERROR-REASON CHAR(2) SSA-NAME3-ERROR-MODULE CHAR(2) SSA-NAME3-ERROR-SEVERITY CHAR(1) SSA-NAME3-ERROR-UNUSED CHAR(3) SSA-NAME3-SECONDARY-RC CHAR(10) SSA-NAME3-WORDS-STACK /* SSA-NAME3-WORDS-STACK must */ SSA-NAME3-WORDS-COUNT NUM(2) /* be large enough to cater */ SSA-NAME3-WORDS OCCURS 8 TIMES /* for the number of entries */ SSA-NAME3-WORD CHAR(24) /* defined in the Algorithm */ SSA-NAME3-WORD-TYPE CHAR(2) /* WORDS-STACK-SIZE parm */ SSA-NAME3-WORD-CATEGORY CHAR(2) SSA-NAME3-ORIGINAL-INIT CHAR(1) FILLER CHAR(3) SSA-NAME3-KEYS-STACK /* SSA-NAME3-KEYS-STACK must */ SSA-NAME3-KEYS-COUNT NUM(2) /* be large enough to cater */ SSA-NAME3-KEYS OCCURS 20 TIMES /* for the number of entries */ SSA-NAME3-KEY CHAR(5) /* defined in the Algorithm */ SSA-NAME3-KEY-TYPE CHAR(2) /* KEYS-STACK-SIZE parameter */ SSA-NAME3-SEARCH-TABLE /* SSA-NAME3-SEARCH-TABLE must */ SSA-NAME3-PREFERRED-KEY CHAR(5) /* be large enough to cater */ SSA-NAME3-SEARCH-RANGES OCCURS 21 TIMES /* for the number of entries */ SSA-NAME3-KEY-FROM CHAR(5) /* defined in the Algorithm */ SSA-NAME3-KEY-TO CHAR(5) /* SEARCH-TABLE-SIZE parm */ SSA-NAME3-RANGE-DEPTH CHAR(2) SSA-NAME3-RANGE-SCALE CHAR(2) SSA-NAME3-RANGE-CONTENTS CHAR(2) SSA-NAME3-RANGE-KEY-TYPE CHAR(2) SSA-NAME3-RANGE-TYPE CHAR(1) SSA-NAME3-RANGE-SEQUENCE CHAR(2) FILLER CHAR(11) SSA-NAME3-CATEGORIES CHAR(20) SSA-NAME3-WORK-AREA CHAR(99999) /* to check if the */ REDEFINE SSA-NAME3-WORK-AREA /* SSA-NAME3-WORK-AREA */ /* is large enough, run */ SSA-NAME3-WORK-FIRST CHAR(42) /* a TestBed NAMESET & */ SSA-NAME3-EXTENDED-RC CHAR(20) /* MATCH Call and check */ /* WSIZE= value */ SSA-NAME3-DUMMY CHAR(1) /* **** OTHER VARIABLES **** */ SSA-NAME3-KEYS-STACK-I NUM(2) /****** PROGRAM LOGIC ******/ /* ------------------------- */ /* initialize SSA parameters */ /* ------------------------- */ INITIALIZE SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES, SSA-NAME3-WORK-AREA. /* ------------------------------------------------ */ /* open cursor for sequential read of customer file */ /* and open output sequential file */ /* ------------------------------------------------ */ DEFINE CUST-SEQUENTIAL-VIEW CURSOR SELECT CUST-ID, CUST-GIVEN-NAMES, CUST-FAMILY-NAME, CUST-ADDR-LINE1, CUST-ADDR-LINE2, CUST-CITY, CUST-STATE, CUST-POSTAL-CODE, CUST-COUNTRY, CUST-BIRTH-DATE FROM CUSTOMER-TABLE END-DEFINE OPEN CUST-SEQUENTIAL-VIEW OPEN OUTPUT SSA-NAME3-KEY-FILE /* -------------------------------------------------------------------- */ /* Read each row from the customer table and Call the NAMESET Service. */ /* For each key returned in the SSA keys stack, write a record to the */ /* output file */ /* -------------------------------------------------------------------- */ WHILE NOT END-OF-CURSOR FETCH CUST-SEQUENTIAL-VIEW IF END-OF-CURSOR BREAK END-IF STRING CUSTOMER-TABLE.CUST-ADDR-LINE1 CUSTOMER-TABLE.CUST-ADDR-LINE2 INTO SSA-NAME3-NAME-IN MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-NAMESET-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAMESET-FUNCTION, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) IF SSA-NAME3-ERROR-NUMBER NOT = ’00’ IF SSA-NAME3-ERROR-NUMBER >= ’90’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY >= ’2’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY = ’1’ PRINT "SSA WARNING: " SSA-NAME3-RESPONSE-CODE END-IF END-IF /* ---------------------------------------- */ /* move the customer data to the ssa record */ /* ---------------------------------------- */ MOVE CUSTOMER-TABLE.CUST-ID TO SSA-NAME3-KEY-FILE.CUST-ID STRING CUSTOMER-TABLE.CUST-GIVEN-NAMES CUSTOMER-TABLE.CUST-FAMILY-NAME INTO SSA-NAME3-KEY-FILE.SSA-NAME3-CUST-NAME MOVE SSA-NAME3-NAME-IN TO SSA-NAME3-KEY-FILE.SSA-NAME3-CUST-STREET STRING CUSTOMER-TABLE.CUST-CITY CUSTOMER-TABLE.CUST-STATE CUSTOMER-TABLE.CUST-COUNTRY INTO SSA-NAME3-KEY-FILE.SSA-NAME3-CUST-LOCALITY MOVE CUSTOMER-TABLE.CUST-POSTAL-CODE TO SSA-NAME3-KEY-FILE.CUST-POSTAL-CODE MOVE CUSTOMER-TABLE.CUST-BIRTH-DATE TO SSA-NAME3-KEY-FILE.CUST-BIRTH-DATE /* ---------------------------------------- */ /* move each SSA key to the SSA record */ /* and write the record */ /* ---------------------------------------- */ MOVE 1 TO SSA-NAME3-KEYS-STACK-I WHILE SSA-NAME3-KEYS-STACK-I <= SSA-NAME3-KEYS-COUNT MOVE SSA-NAME3-KEY (SSA-NAME3-KEYS-STACK-I) TO SSA-NAME3-CUST-KEY WRITE SSA-NAME3-KEY-FILE ADD 1 TO SSA-NAME3-KEYS-STACK-I END-WHILE END-WHILE CLOSE CUST-SEQUENTIAL-VIEW CLOSE SSA-NAME3-KEY-FILE STOP SSA-NAME3-ERROR-ABORT PRINT "SSA ERROR: " SSA-NAME3-RESPONSE-CODE ABORT /*---------------------------------------------------------------------------*/ /* SEARCH & MATCH EXAMPLE 1 */ /* */ /* Purpose: Search for a person’s name and display the */ /* results in ranked order by the probability of */ /* match. This example optionally uses a postal/zip */ /* code to refine the list further, but any other data */ /* (e.g.. date of birth, street address) could be used */ /* to refine the list as long as the scoring scheme */ /* is set up appropriately. This example limits the */ /* search results to 200 records. */ /* Description: Accept a name and optionally a postal code from */ /* screen. Call NAMESET to get the search ranges then */ /* retrieve the candidate records from the db table. */ /* For each record returned, score it against the */ /* search data. If its score is greater than a pre- */ /* determined cut-off score, add it to a program */ /* array. When all of the candidate records have been */ /* read and scored, sort the array descending by */ /* score and display to the screen. */ /* Pre-requisites: 1. Requires the PERSON Algorithm to be customized */ /* and generated as part of the SSA Service Group */ /* 2. Requires a Matching Scheme to be customized */ /* and generated as part of the SSA Service Group */ /* in this code we call it PERSZIP) */ /* 3. Requires access to the executable SSA Service */ /* Group in the environment where the program is */ /* to run. */ /* 4. Requires the SSA database table to be loaded */ /* with the SSA 5 byte binary Keys. */ /* */ /*--------------------------------------------------------------------------- */ /****** DATABASE DEFINITIONS ******/ SSA-NAME3-TABLE /* SSA-NAME3 Key db table */ SSA-NAME3-CUST-KEY CHAR(5) CUST-ID CHAR(10) SSA-NAME3-CUST-NAME CHAR(50) SSA-NAME3-CUST-STREET CHAR(80) SSA-NAME3-CUST-LOCALITY CHAR(45) CUST-POSTAL-CODE CHAR(8) CUST-BIRTH-DATE CHAR(10) /****** VARIABLE DEFINITIONS ******/ /*** SSA NAMESET PARAMETERS ***/ SSA-NAME3-NAMESET-SERVICE CHAR(8) VALUE ’NAMESETP’ /* the NAMESET Service name */ /* must be defined in the */ /* Algorithm Definition */ SSA-NAME3-NAMESET-FUNCTION CHAR(100) VALUE ’*CUSTOMSET=PERSON,SECONDARY,FILESIZE=99999*’ /* PERSON generates probes */ /* for combinations of words */ /* and initials to facilitate */ /* finding person names. The */ /* CUSTOMSET probes appear */ /* first in the search table. */ /* SECONDARY causes extra */ /* ranges to be built where */ /* for any secondary name */ /* rules defined in the Edit- */ /* list. */ /* FILESIZE= must approximate */ /* the number of customer */ /* records in the database */ /* if SCALE is going to be */ /* used to control searches. */ SSA-NAME3-NAME-IN CHAR(50) /* SSA-NAME3-NAME-IN & SSA-NAME3-NAME- */ /* CLEAN must be the same */ /* length as specified in the */ /* Algorithm NAME-LENGTH */ SSA-NAME3-NAME-CLEAN CHAR(50) /* parameter. */ SSA-NAME3-RESPONSE-CODE CHAR(20) REDEFINE SSA-NAME3-RESPONSE-CODE SSA-NAME3-ERROR-NUMBER CHAR(2) SSA-NAME3-ERROR-REASON CHAR(2) SSA-NAME3-ERROR-MODULE CHAR(2) SSA-NAME3-ERROR-SEVERITY CHAR(1) SSA-NAME3-ERROR-UNUSED CHAR(3) SSA-NAME3-SECONDARY-RC CHAR(10) SSA-NAME3-WORDS-STACK /* SSA-NAME3-WORDS-STACK must */ SSA-NAME3-WORDS-COUNT NUM(2) /* be large enough to cater */ SSA-NAME3-WORDS OCCURS 8 TIMES /* for the number of entries */ SSA-NAME3-WORD CHAR(24) /* defined in the Algorithm */ SSA-NAME3-WORD-TYPE CHAR(2) /* WORDS-STACK-SIZE parameter */ SSA-NAME3-WORD-CATEGORY CHAR(2) SSA-NAME3-ORIGINAL-INIT CHAR(1) FILLER CHAR(3) SSA-NAME3-KEYS-STACK /* SSA-NAME3-KEYS-STACK must */ SSA-NAME3-KEYS-COUNT NUM(2) /* be large enough to cater for */ SSA-NAME3-KEYS OCCURS 20 TIMES /* the number of entries */ SSA-NAME3-KEY CHAR(5) /* defined in the Algorithm */ SSA-NAME3-KEY-TYPE CHAR(2) /* KEYS-STACK-SIZE parameter */ SSA-NAME3-SEARCH-TABLE /* SSA-NAME3-SEARCH-TABLE */ SSA-NAME3-PREFERRED-KEY CHAR(5) /* must be large enough */ SSA-NAME3-SEARCH-RANGES OCCURS 21 TIMES /* to cater for the */ SSA-NAME3-KEY-FROM CHAR(5) /* number of entries */ SSA-NAME3-KEY-TO CHAR(5) /* defined in the */ SSA-NAME3-RANGE-DEPTH CHAR(2) /* Algorithm */ SSA-NAME3-RANGE-SCALE CHAR(2) /* SEARCH-TABLE-SIZE */ SSA-NAME3-RANGE-CONTENTS CHAR(2) /* parameter */ SSA-RANGE-KEY-TYPE CHAR(2) SSA-RANGE-TYPE CHAR(1) SSA-RANGE-SEQUENCE CHAR(2) FILLER CHAR(11) SSA-CATEGORIES CHAR(20) SSA-WORK-AREA CHAR(99999) /* to check if the */ REDEFINE SSA-WORK-AREA /* SSA-WORK-AREA is large */ SSA-NAME3-WORK-FIRST CHAR(42) /* enough, run a TestBed */ SSA-NAME3-EXTENDED-RC CHAR(20) /* NAMESET & MATCH Call */ /* and check the WSIZE= */ /* value. */ SSA-NAME3-WORK-AREA-SIZE CHAR(6) VALUE ’099999’ /* zoned numeric value */ /* equal to the Work-area */ /* size. Only checked if */ /* PASSING-WORKAREA-SIZE */ /* specified in the */ /* Service Group. */ SSA-NAME3-WORK-REST CHAR(99931) SSA-NAME3-DUMMY CHAR(1) /**** SSA MATCH PARAMETERS ****/ SSA-NAME3-MATCH-SERVICE CHAR(8) VALUE ’MATCH’ /* is always MATCH */ SSA-NAME3-MATCH-FUNCTION CHAR(32) VALUE ’*SCORE-ONLY*’ /* Request a Score only in */ /* the result field. */ SSA-NAME3-MATCH-SCHEME CHAR(8) VALUE ’PERSZIP’ /* the SCHEME name must be */ /* defined in the Scheme */ /* definition file */ SSA-NAME3-MATCH-RESULT CHAR(3) REDEFINE SSA-NAME3-MATCH-RESULT SSA-NAME3-MATCH-SCORE NUM(3) SSA-NAME3-MATCH-SEARCH-DATA /* Search Data and File */ SSA-NAME3-MATCH-SEARCH-NAME CHAR(50) /* Data definitions must */ SSA-NAME3-MATCH-SEARCH-PCODE CHAR(8) /* match the layout of the */ SSA-NAME3-MATCH-FILE-DATA /* Scheme being used */ SSA-NAME3-MATCH-FILE-NAME CHAR(50) /* (SSA-NAME3-MATCH-SCHEME) */ SSA-NAME3-MATCH-FILE-PCODE CHAR(8) /* Check the field offsets */ /* & lengths */ SSA-NAME3-MATCH-MTBL CHAR(147) REDEFINE SSA-NAME3-MATCH-MTBL SSA-NAME3-MTBL-HEADER CHAR(25) SSA-NAME3-MTBL-METHOD-ENTRY OCCURS 2 SSA-NAME3-METHOD-NAME CHAR(8) SSA-NAME3-METHOD-EP CHAR(8) SSA-NAME3-METHOD-ALG CHAR(8) SSA-NAME3-FIELD-OFFSET CHAR(5) SSA-NAME3-FIELD-LENGTH CHAR(3) SSA-NAME3-METHOD-RESP CHAR(20) SSA-NAME3-METHOD-SCORE CHAR(3) SSA-NAME3-METHOD-WEIGHT CHAR(3) SSA-NAME3-METHOD-WGTMOD CHAR(3) /***** OTHER VARIABLES ******/ INPUT-SCREEN-VARIABLES INPUT-NAME CHAR(50) INPUT-POSTAL-CODE CHAR(8) CANDIDATE-ARRAY CANDIDATE-CUST-ID CHAR(10) OCCURS 999 MATCH-ARRAY MATCH-CUST-ID CHAR(10) OCCURS 200 MATCH-CUST-NAME CHAR(50) OCCURS 200 MATCH-CUST-POSTAL-CODE CHAR(8) OCCURS 200 MATCH-CUST-BIRTH-DATE CHAR(10) OCCURS 200 MATCH-SCORE NUM(3) OCCURS 200 SSA-NAME3-CUTOFF-SCORE NUM(3) VALUE 70 /* user assigned value */ SSA-NAME3-STAB-I NUM(2) MATCH-I NUM(2) CANDIDATE-I NUM(4) WORK-I NUM(3) WORK-II NUM(3) SORT-CUST-ID CHAR(10) SORT-SCORE NUM(3) /****** PROGRAM LOGIC ******/ /* ------------------------- */ /* initialize SSA parameters */ /* ------------------------- */ INITIALIZE SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES. /* --------------------------------------------------- */ /* program loop to control display of the input screen */ /* --------------------------------------------------- */ WHILE NOT ESCAPE-SELECTED INITIALIZE SSA-NAME3-STAB-I, CANDIDATE-I, MATCH-I, CANDIDATE-ARRAY, MATCH-ARRAY /* --------------------------- */ /* get search data from screen */ /* --------------------------- */ ACCEPT INPUT-NAME, INPUT-ZIP FROM SCREEN IF ESCAPE-SELECTED BREAK END-IF /* -------------------------------------------------------------- */ /* Call NAMESET with the search name to get the search key ranges */ /* -------------------------------------------------------------- */ MOVE INPUT-NAME TO SSA-NAME3-NAME-IN MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-NAMESET-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAMESET-FUNCTION, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) IF SSA-NAME3-ERROR-NUMBER NOT = ’00’ IF SSA-NAME3-ERROR-NUMBER >= ’90’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY >= ’2’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY = ’1’ DISPLAY "SSA WARNING: " SSA-NAME3-RESPONSE-CODE END-IF END-IF /* ----------------------------------- */ /* set up the search data for MATCHing */ /* ----------------------------------- */ MOVE INPUT-NAME TO SSA-NAME3-MATCH-SEARCH-NAME MOVE INPUT-POSTAL-CODE TO SSA-NAME3-MATCH-SEARCH-PCODE /* ----------------------------------------------------------- */ /* program loop to control the processing of the search ranges */ /* ----------------------------------------------------------- */ MOVE 1 TO SSA-NAME3-STAB-I WHILE SSA-NAME3-RANGE-CONTENTS (SSA-NAME3-STAB-I) NOT = ’00’ /* ---------------------------------------------------------- */ /* for a positive search (SSA-NAME3-SET-ID = C), break if the */ /* estimated number of records exceeds 250 (SCALE=23) */ /* ---------------------------------------------------------- */ IF SSA-NAME3-RANGE-SCALE (SSA-NAME3-STAB-I) GT ’23’ BREAK END-IF /* ------------------------------------------------ */ /* open cursor for sequential read of SSA key table */ /* ------------------------------------------------ */ DEFINE SSA-NAME3-SEARCH-CANDIDATE CURSOR SELECT CUST-ID, SSA-NAME3-CUST-NAME, CUST-POSTAL-CODE, CUST-BIRTH-DATE FROM SSA-NAME3-TABLE WHERE SSA-NAME3-CUST-KEY >= SSA-NAME3-KEY-FROM (SSA-NAME3-STAB-I) AND SSA-NAME3-CUST-KEY <= SSA-NAME3-KEY-TO (SSA-NAME3-STAB-I) END-DEFINE OPEN SSA-NAME3-SEARCH-CANDIDATE /* ---------------------------------------------------------------- */ /* program loop to control the reading of records from the database */ /* ---------------------------------------------------------------- */ WHILE NOT END-OF-CURSOR FETCH SSA-NAME3-SEARCH-CANDIDATE IF END-OF-CURSOR CLOSE SSA-NAME3-SEARCH-CANDIDATE BREAK END-IF /* ------------------------------------------------------- */ /* check in the candidates array if we have processed this */ /* record in a previous search range and if so don’t */ /* score it again */ /* ------------------------------------------------------- */ IF CANDIDATE-I = 999 /* max number of candidates */ BREAK /* allowed in this program */ END-IF PERFORM CHECK-DUPLICATE-CANDIDATE IF DUPLICATE-CANDIDATE CONTINUE /* go fetch the next record */ END-IF /* -------------------------------- */ /* setup the file data for MATCHing */ /* -------------------------------- */ MOVE SSA-NAME3-CUST-NAME TO SSA-NAME3-MATCH-FILE-NAME MOVE CUST-POSTAL-CODE TO SSA-NAME3-MATCH-FILE-PCODE /* ----------------------------------------------------------- */ /* Call MATCH to compare to file record with the search record */ /* ----------------------------------------------------------- */ MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-MATCH-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-MATCH-FUNCTION, SSA-NAME3-MATCH-SCHEME, SSA-NAME3-MATCH-RESULT, SSA-NAME3-MATCH-SEARCH-DATA, SSA-NAME3-MATCH-FILE-DATA, SSA-NAME3-MATCH-MTBL, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) IF SSA-NAME3-ERROR-NUMBER NOT = ’00’ IF SSA-NAME3-ERROR-NUMBER >= ’90’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY >= ’2’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY = ’1’ DISPLAY "SSA WARNING: " SSA-NAME3-RESPONSE-CODE END-IF END-IF /* ------------------------------------------------------- */ /* if the Score is greater than the cut-off score, add the */ /* record to the match array */ /* ------------------------------------------------------- */ IF SSA-NAME3-MATCH-SCORE >= SSA-NAME3-CUTOFF-SCORE ADD 1 TO MATCH-I IF MATCH-I > 200 BREAK END-IF MOVE CUST-ID TO MATCH-CIST-ID (MATCH-I) MOVE SSA-NAME3-CUST-NAME TO MATCH-CUST-NAME (MATCH-I) MOVE CUST-POSTAL-CODE TO MATCH-CUST-POSTAL-CODE (MATCH-I) MOVE CUST-BIRTH-DATE TO MATCH-CUST-BIRTH-DATE (MATCH-I) MOVE SSA-NAME3-MATCH-SCORE TO MATCH-SCORE (MATCH-I) END-IF END-WHILE /* Fetch Candidate Records */ IF CANDIDATE-I = 999 OR MATCH-I > 200 BREAK END-IF /* --------------------------------------------------------- */ /* Cater for all search strategy types - for PROBE or */ /* NEGATIVE search ranges, process all of that type’s */ /* search ranges without stopping. For POSITIVE searches, */ /* process one range at a time and display that to the user. */ /* Here is a summary of the Range Types used below: */ /* P: Customset Probes/Ranges */ /* 2: Secondary Search Ranges */ /* S: Code Probe */ /* C: Cascade Ranges (Positive Search) */ /* N: Negative Ranges */ /* W: Negative Word Probes */ /* I: Negative Word+Initial Probes */ /* B: Bad Key Range */ /* --------------------------------------------------------- */ IF ((SSA-NAME3-RANGE-TYPE(SSA-NAME3-STAB-I) = ’N’ OR (SSA-NAME3-RANGE-TYPE(SSA-NAME3-STAB-I) = ’W’ OR (SSA-NAME3-RANGE-TYPE(SSA-NAME3-STAB-I) = ’I’ OR (SSA-NAME3-RANGE-TYPE(SSA-NAME3-STAB-I) = ’B’) OR ((SSA-NAME3-RANGE-TYPE(SSA-NAME3-STAB-I) = ’P’ OR (SSA-NAME3-RANGE-TYPE(SSA-NAME3-STAB-I) = ’2’ OR (SSA-NAME3-RANGE-TYPE(SSA-NAME3-STAB-I) = ’S’) AND SSA-NAME3-RANGE-TYPE(SSA-NAME3-STAB-I + 1) != ’C’)) ADD 1 TO SSA-NAME3-STAB-I CONTINUE /* go process the next search range */ END-IF /* ----------------------------------*/ /* display the results of the search */ /* ----------------------------------*/ IF MATCH-I > 0 PERFORM DISPLAY-MATCHES IF ESCAPE-SELECTED BREAK END-IF END-IF ADD 1 TO SSA-NAME3-STAB-I END-WHILE /* NAMESET Search Ranges */ IF CANDIDATE-I = 999 OR MATCH-I > 200 OR SSA-NAME3-RANGE-SCALE (SSA-NAME3-STAB-I) > SSA-NAME3-CUTOFF-SCALE DISPLAY ’TOO MANY RECORDS FOUND’ BREAK END-IF IF MATCH-I = 0 DISPLAY MESSAGE ’NO RECORDS FOUND MATCHING SEARCH CRITERIA’ END-IF END-WHILE /* Input Search Data */ /*----------------------------------------*/ DEFINE SUBROUTINE CHECK-DUPLICATE-CANDIDATE /*----------------------------------------*/ MOVE FALSE TO DUPLICATE-CANDIDATE IF CANDIDATE-I > 0 INITIALIZE WORK-I WHILE WORK-I <= CANDIDATE-I ADD 1 TO WORK-I IF CUST-ID = CANDIDATE-CUST-ID (WORK-I) MOVE TRUE TO DUPLICATE-CANDIDATE BREAK END-IF END-WHILE END-IF IF NOT DUPLICATE-CANDIDATE ADD 1 TO CANDIDATE-I MOVE CUST-ID TO CANDIDATE-CUST-ID (CANDIDATE-I) END-IF END-DEFINE /*-----------------------------*/ DEFINE SUBROUTINE DISPLAY-MATCHES /*-----------------------------*/ PERFORM SORT-CANDIDATES /* -------------------------------------------- */ /* Display the List Box, or if working with a */ /* a fixed screen, display 15 records at */ /* a time to the screen similar to below. */ /* -------------------------------------------- */ MOVE 1 TO SCREEN-START-I WHILE SCREEN-I <= MATCH-I MOVE SCREEN-START-I TO SCREEN-END-I ADD 14 TO SCREEN-END-I OUTPUT MATCH-ARRAY (SCREEN-START-I - SCREEN-END-I) IF ESCAPE-SELECTED BREAK END-IF IF PGUP-SELECTED IF SCREEN-START-I = 1 DISPLAY MESSAGE ’TOP OF LIST’ ELSE SUBTRACT 15 FROM START-I END-IF END-IF IF PGDN-SELECTED IF SCREEN-END-I >= MATCH-I DISPLAY MESSAGE ’END OF LIST’ ELSE ADD 15 TO SCREEN-START-I END-IF END-IF END-WHILE END-DEFINE /*-----------------------------*/ DEFINE SUBROUTINE SORT-CANDIDATES /*-----------------------------*/ INITIALIZE WORK-I WHILE WORK-I < MATCH-I ADD 1 TO WORK-I MOVE WORK-I TO WORK-II WHILE WORK-II < MATCH-I ADD 1 TO WORK-II IF MATCH-SCORE (WORK-I) < MATCH-SCORE (WORK-II) MOVE MATCH-CUST-ID (WORK-II) TO SORT-CUST-ID MOVE MATCH-SCORE (WORK-II) TO SORT-SCORE MOVE MATCH-CUST-ID (WORK-I) TO MATCH-CUST-ID (WORK-II) MOVE MATCH-SCORE (WORK-I) TO MATCH-SCORE (WORK-II) MOVE SORT-CUST-ID TO MATCH-CUST-ID (WORK-I) MOVE SORT-SCORE TO MATCH-SCORE (WORK-I) END-IF END-WHILE END-WHILE END-DEFINE /*-----------------------------*/ DEFINE SUBROUTINE SSA-NAME3-ERROR-ABORT /*-----------------------------*/ DISPLAY ’SSA ERROR:’ SSA-NAME3-RESPONSE-CODE STOP END-DEFINE /*------------------------------------------------------------------------ */ /* SEARCH & MATCH EXAMPLE 2 */ /* */ /* Purpose: Search for a company prior to adding it as a new */ /* customer. Displays the definite matches only, */ /* based on name and street address. If no match */ /* exists, store the new record on the customer db */ /* Uses 8 byte SSA keys. */ /* Description: Accept a company’s name and other details from the */ /* screen. Call NAMESET to get the search ranges then */ /* retrieve the candidate records from the db table. */ /* For each record returned, match it against the */ /* search data. If its score is greater than a pre- */ /* determined cut-off score, add it to a program */ /* array. When all of the candidate records have been */ /* read and scored, display to the screen. If no */ /* match is found, or the user decides that none */ /* found match, add the record to the customer db. */ /* Pre-requisites: 1. Requires the COMPANY Algorithm to be customized */ /* and generated as part of the SSA Service Group */ /* 2. Requires a Matching Scheme to be customized */ /* and generated as part of the SSA Service Group */ /* (in this code we call it COMPADDR) */ /* 3. Requires access to the executable SSA Service */ /* Group in the environment where the program is */ /* to run. */ /* 4. Requires the SSA database table to be loaded */ /* with the SSA 8 byte binary Keys. */ /* */ /*------------------------------------------------------------------------ */ /****** DATABASE DEFINITIONS ******/ SSA-NAME3-TABLE /* SSA Key db table */ SSA-NAME3-CUST-KEY CHAR(5) CUST-ID CHAR(10) SSA-NAME3-CUST-NAME CHAR(100) SSA-NAME3-CUST-STREET CHAR(80) SSA-NAME3-CUST-LOCALITY CHAR(45) CUST-POSTAL-CODE CHAR(8) CUSTOMER-TABLE /* customer db table */ CUST-ID CHAR(10) CUST-COMPANY-NAME CHAR(100) CUST-ADDR-LINE1 CHAR(40) CUST-ADDR-LINE2 CHAR(40) CUST-CITY CHAR(20) CUST-STATE CHAR(3) CUST-POSTAL-CODE CHAR(8) CUST-COUNTRY CHAR(20) /****** VARIABLE DEFINITIONS ******/ /*** SSA NAMESET PARAMETERS ***/ SSA-NAME3-NAMESET-SERVICE CHAR(8) VALUE ’NAMESETC’ /* the NAMESET Service name */ /* must be defined in the */ /* Algorithm Definition */ SSA-NAME3-NAMESET-FUNCTION CHAR(100) VALUE ’*NEG,FULLSEARCH,PROBESWORD*’ /* ’PROBESWORD’ generates */ /* search probes for each */ /* word in the name. */ /* ’NEG,FULLSEARCH’ generates */ /* negative search ranges for */ /* all combinations of two */ /* words in the name. */ SSA-NAME3-NAME-IN CHAR(100) /* SSA-NAME3-NAME-IN & */ /* SSA-NAME3-NAME-CLEAN */ /* must be the same length */ /* as specified in the */ /* Algorithm NAME-LENGTH */ /* parameter */ SSA-NAME3-NAME-CLEAN CHAR(100) SSA-NAME3-RESPONSE-CODE CHAR(20) REDEFINE SSA-NAME3-RESPONSE-CODE SSA-NAME3-ERROR-NUMBER CHAR(2) SSA-NAME3-ERROR-REASON CHAR(2) SSA-NAME3-ERROR-MODULE CHAR(2) SSA-NAME3-ERROR-SEVERITY CHAR(1) SSA-NAME3-ERROR-UNUSED CHAR(3) SSA-NAME3-SECONDARY-RC CHAR(10) SSA-NAME3-WORDS-STACK /* SSA-NAME3-WORDS-STACK */ SSA-NAME3-WORDS-COUNT NUM(2) /* must be large enough to */ SSA-NAME3-WORDS OCCURS 8 TIMES /* cater for the number of */ SSA-NAME3-WORD CHAR(24) /* entries defined in the */ SSA-NAME3-WORD-TYPE CHAR(2) /* Algorithm */ SSA-NAME3-WORD-CATEGORY CHAR(2) /* WORDS-STACK-SIZE */ SSA-NAME3-ORIGINAL-INIT CHAR(1) /* parameter */ FILLER CHAR(3) SSA-NAME3-KEYS-STACK /* SSA-NAME3-KEYS-STACK must */ SSA-NAME3-KEYS-COUNT NUM(2) /* be large enough to cater */ SSA-NAME3-KEYS OCCURS 20 TIMES /* for the number of entries */ SSA-NAME3-KEY CHAR(8) /* defined in the Algorithm */ SSA-NAME3-KEY-TYPE CHAR(2) /* KEYS-STACK-SIZE parameter */ SSA-NAME3-SEARCH-TABLE /* SSA-NAME3-SEARCH-TABLE */ SSA-NAME3-PREFERRED-KEY CHAR(8) /* must be large enough to */ SSA-NAME3-SEARCH-RANGES OCCURS 21 TIMES /* cater for the number of */ SSA-NAME3-KEY-FROM CHAR(8) /* entries defined in the */ SSA-NAME3-KEY-TO CHAR(8) /* Algorithm */ SSA-NAME3-RANGE-DEPTH CHAR(2) /* SEARCH-TABLE-SIZE */ SSA-NAME3-RANGE-SCALE CHAR(2) /* parameter */ SSA-NAME3-RANGE-CONTENTS CHAR(2) SSA-NAME3-RANGE-KEY-TYPE CHAR(2) SSA-NAME3-RANGE-TYPE CHAR(1) SSA-NAME3-RANGE-SEQUENCE CHAR(2) FILLER CHAR(11) SSA-NAME3-CATEGORIES CHAR(20) SSA-NAME3-WORK-AREA CHAR(99999) /* to check if the */ REDEFINE SSA-NAME3-WORK-AREA /* WORK-AREA is large */ SSA-NAME3-WORK-FIRST CHAR(42) /* enough, run a TestBed */ SSA-NAME3-EXTENDED-RC CHAR(20) /* NAMESET & MATCH Call */ /* and check the WSIZE= */ /* value. */ SSA-NAME3-WORK-AREA-SIZE CHAR(6) VALUE ’099999’ /* zoned numeric value */ /* equal to the */ /* Work-area size. Only */ /* checked if */ /* PASSING-WORKAREA-SIZE */ /* specified in the */ /* Service Group. */ SSA-NAME3-WORK-REST CHAR(99931) SSA-NAME3-DUMMY CHAR(1) /**** SSA MATCH PARAMETERS ****/ SSA-NAME3-MATCH-SERVICE CHAR(8) VALUE ’MATCH’ /* is always MATCH */ SSA-NAME3-MATCH-FUNCTION CHAR(32) VALUE ’*LIMIT=90*’ /* if a record scores 90 */ /* or above, set the */ /* ruling to ’A’ (accept) */ SSA-NAME3-MATCH-SCHEME CHAR(8) VALUE ’COMPADDR’ /* the SCHEME name must be */ /* defined in the Scheme */ /* definition file */ SSA-NAME3-MATCH-RESULT CHAR(250) REDEFINE SSA-NAME3-MATCH-RESULT SSA-NAME3-MATCH-SCORE NUM(3) SSA-NAME3-MATCH-RULING CHAR(1) SSA-NAME3-MATCH-SEARCH-DATA /* Search Data and File */ SSA-NAME3-MATCH-SEARCH-NAME CHAR(100) /* Data definitions must */ SSA-NAME3-MATCH-SEARCH-STREET CHAR(80) /* match the layout of the */ /* Scheme being used (i.e. */ SSA-NAME3-MATCH-FILE-DATA /* SSA-NAME3-SCHEME-NAME) */ SSA-NAME3-MATCH-FILE-NAME CHAR(100) /* Check the field offsets */ SSA-NAME3-MATCH-FILE-STREET CHAR(80) /* & lengths */ SSA-NAME3-MATCH-MTBL CHAR(147) REDEFIN SSA-NAME3-MATCH-MTBL SSA-NAME3-MTBL-HEADER CHAR(25) SSA-NAME3-MTBL-METHOD-ENTRY OCCURS 2 SSA-NAME3-METHOD-NAME CHAR(8) SSA-NAME3-METHOD-EP CHAR(8) SSA-NAME3-METHOD-ALG CHAR(8) SSA-NAME3-FIELD-OFFSET CHAR(5) SSA-NAME3-FIELD-LENGTH CHAR(3) SSA-NAME3-METHOD-RESP CHAR(20) SSA-NAME3-METHOD-SCORE CHAR(3) SSA-NAME3-METHOD-WEIGHT CHAR(3) SSA-NAME3-METHOD-WGTMOD CHAR(3) /***** OTHER VARIABLES ******/ INPUT-SCREEN-VARIABLES INPUT-COMPANY-NAME CHAR(100) INPUT-ADDR-LINE1 CHAR(40) INPUT-ADDR-LINE2 CHAR(40) INPUT-CITY CHAR(20) INPUT-STATE CHAR(3) INPUT-POSTAL-CODE CHAR(8) INPUT-COUNTRY CHAR(20) SCREEN-ARRAY /* allow for total of 15 dups */ SCREEN-SELECT CHAR(1) OCCURS 15 SCREEN-CUST-ID CHAR(10) OCCURS 15 SCREEN-CUST-NAME CHAR(40) OCCURS 15 SCREEN-CUST-STREET CHAR(30) OCCURS 15 CANDIDATE-ARRAY CANDIDATE-CUST-ID CHAR(10) OCCURS 999 SSA-NAME3-KEYS-STACK-I NUM(2) SSA-NAME3-STAB-I NUM(2) SCREEN-I NUM(2) CANDIDATE-I NUM(4) WORK-I NUM(2) MATCH-CUST-ID CHAR(10) /****** PROGRAM LOGIC ******/ /* ------------------------- */ /* initialize SSA parameters */ /* ------------------------- */ INITIALIZE SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES. /* --------------------------------------------------- */ /* program loop to control display of the input screen */ /* --------------------------------------------------- */ WHILE NOT ESCAPE-SELECTED INITIALIZE SSA-NAME3-STAB-I, CANDIDATE-I, SCREEN-I, MATCH-CUST-ID /* --------------------------- */ /* get search data from screen */ /* --------------------------- */ ACCEPT INPUT-COMPANY-NAME, INPUT-ADDR-LINE1, INPUT-ADDR-LINE2, INPUT-CITY, INPUT-STATE, INPUT-POSTAL-CODE, INPUT-COUNTRY FROM SCREEN IF ESCAPE-SELECTED BREAK END-IF /* -------------------------------------------------------------- */ /* Call NAMESET with the search name to get the search key ranges */ /* -------------------------------------------------------------- */ MOVE INPUT-COMPANY-NAME TO SSA-NAME3-NAME-IN MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-NAMESET-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAMESET-FUNCTION, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) IF SSA-NAME3-ERROR-NUMBER NOT = ’00’ IF SSA-NAME3-ERROR-NUMBER >= ’90’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY >= ’2’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY = ’1’ DISPLAY "SSA WARNING: " SSA-NAME3-RESPONSE-CODE END-IF END-IF /* ----------------------------------- */ /* set up the search data for MATCHing */ /* ----------------------------------- */ MOVE INPUT-NAME TO SSA-NAME3-MATCH-SEARCH-NAME STRING INPUT-ADDR-LINE-1, INPUT-ADDR-LINE2 INTO SSA-NAME3-MATCH-SEARCH-STREET /* ----------------------------------------------------------- */ /* program loop to control the processing of the search ranges */ /* ----------------------------------------------------------- */ MOVE 1 TO SSA-NAME3-STAB-I WHILE SSA-NAME3-RANGE-CONTENTS (SSA-NAME3-STAB-I) NOT = ’00’ /* ------------------------------------------------ */ /* open cursor for sequential read of SSA key table */ /* ------------------------------------------------ */ DEFINE SSA-NAME3-SEARCH-CANDIDATE CURSOR SELECT CUST-ID, SSA-NAME3-CUST-NAME, CUST-POSTAL-CODE, CUST-BIRTH-DATE FROM SSA-NAME3-TABLE WHERE SSA-NAME3-CUST-KEY >= SSA-NAME3-KEY-FROM (SSA-NAME3-STAB-I) AND SSA-NAME3-CUST-KEY <= SSA-NAME3-KEY-TO (SSA-NAME3-STAB-I) END-DEFINE OPEN SSA-NAME3-SEARCH-CANDIDATE /* ---------------------------------------------------------------- */ /* program loop to control the reading of records from the database */ /* ---------------------------------------------------------------- */ WHILE NOT END-OF-CURSOR FETCH SSA-NAME3-SEARCH-CANDIDATE IF END-OF-CURSOR CLOSE SSA-NAME3-SEARCH-CANDIDATE BREAK END-IF /* ------------------------------------------------------- */ /* check in the candidates array if we have processed this */ /* record in a previous search range and if so don’t */ /* score it again */ /* ------------------------------------------------------- */ IF CANDIDATE-I = 999 /* max number of candidates */ BREAK /* allowed in this program */ END-IF PERFORM CHECK-DUPLICATE-CANDIDATE IF DUPLICATE-CANDIDATE CONTINUE /* go fetch the next record */ END-IF /* ------------------------------- */ /* setup the file data for scoring */ /* ------------------------------- */ MOVE SSA-NAME3-CUST-NAME TO SSA-NAME3-MATCH-FILE-NAME MOVE SSA-NAME3-CUST-STREET TO SSA-NAME3-MATCH-FILE-STREET /* ------------------------------------------------------------- */ /* Call MATCH to compare to file record with the search record */ /* ------------------------------------------------------------- */ MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-MATCH-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-MATCH-FUNCTION, SSA-NAME3-MATCH-SCHEME, SSA-NAME3-MATCH-RESULT, SSA-NAME3-MATCH-SEARCH-DATA, SSA-NAME3-MATCH-FILE-DATA, SSA-NAME3-MATCH-MTBL, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) IF SSA-NAME3-ERROR-NUMBER NOT = ’00’ IF SSA-NAME3-ERROR-NUMBER >= ’90’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY >= ’2’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY = ’1’ DISPLAY "SSA WARNING: " SSA-NAME3-RESPONSE-CODE END-IF END-IF /* ------------------------------------------------------- */ /* if the record is marked as "accepted", add it to the */ /* screen array */ /* ------------------------------------------------------- */ IF SSA-NAME3-RULING = ’A’ ADD 1 TO SCREEN-I IF SCREEN-I > 15 BREAK END-IF MOVE CUST-ID TO SCREEN-CIST-ID (SCREEN-I) MOVE SSA-NAME3-CUST-NAME TO SCREEN-CUST-NAME (SCREEN-I) MOVE SSA-NAME3-CUST-STREET TO SCREEN-CUST-STREET (SCREEN-I) END-IF END-WHILE /* Fetch Candidate Records */ IF CANDIDATE-I = 999 OR MATCH-I > 15 BREAK END-IF ADD 1 TO SSA-NAME3-STAB-I END-WHILE /* NAMESET Search Ranges */ IF CANDIDATE-I = 999 OR MATCH-I > 15 DISPLAY ’TOO MANY RECORDS FOUND’ CONTINUE /* go back and display input screen */ END-IF /* ----------------------------------*/ /* display the results of the search */ /* ----------------------------------*/ IF MATCH-I > 0 PERFORM DISPLAY-SCREEN IF MATCH-CUST-ID = NULL OR ESCAPE-SELECTED DISPLAY ’NO RECORD SELECTED’ END-IF ELSE DISPLAY MESSAGE ’NO RECORDS FOUND MATCHING SEARCH CRITERIA’ END-IF IF MATCH-CUST-ID = NULL DISPLAY MESSAGE ’ADDING NEW CUSTOMER RECORD’ PERFORM ADD-NEW-CUSTOMER DISPLAY MESSAGE ’NEW CUSTOMER ADDED’ END-IF END-WHILE /* Input Search Data */ /*----------------------------------------*/ DEFINE SUBROUTINE CHECK-DUPLICATE-CANDIDATE /*----------------------------------------*/ MOVE FALSE TO DUPLICATE-CANDIDATE IF CANDIDATE-I > 0 INITIALIZE WORK-I WHILE WORK-I <= CANDIDATE-I ADD 1 TO WORK-I IF CUST-ID = CANDIDATE-CUST-ID (WORK-I) MOVE TRUE TO DUPLICATE-CANDIDATE BREAK END-IF END-WHILE END-IF IF NOT DUPLICATE-CANDIDATE ADD 1 TO CANDIDATE-I MOVE CUST-ID TO CANDIDATE-CUST-ID (CANDIDATE-I) END-IF END-DEFINE /* -------------------------- */ DEFINE SUBROUTINE DISPLAY-SCREEN /* -------------------------- */ OUTPUT SCREEN-ARRAY IF ESCAPE-SELECTED BREAK END-IF /* ------------------------------------------- */ /* let the user select a match from the screen */ /* ------------------------------------------- */ INITIALIZE WORK-I WHILE WORK-I <= SCREEN-I ADD 1 TO WORK-I IF SCREEN-SELECT (WORK-I) MOVE SCREEN-CUST-ID TO MATCH-CUST-ID BREAK END-IF END-WHILE END-DEFINE /* ---------------------------- */ DEFINE SUBROUTINE ADD-NEW-CUSTOMER /* ---------------------------- */ INITIALIZE CUSTOMER-TABLE, SSA-NAME3-TABLE /* ------------------------------ */ /* set up the customer record */ /* ------------------------------ */ ASSIGN UNIQUE ID TO CUSTOMER-TABLE.CUST-ID MOVE INPUT-COMPANY-NAME TO CUSTOMER-TABLE.CUST-COMPANY-NAME MOVE INPUT-ADDR-LINE1 TO CUSTOMER-TABLE.CUST-ADDR-LINE1 MOVE INPUT-ADDR-LINE2 TO CUSTOMER-TABLE.CUST-ADDR-LINE2 MOVE INPUT-CITY TO CUSTOMER-TABLE.CUST-CITY MOVE INPUT-STATE TO CUSTOMER-TABLE.CUST-STATE MOVE INPUT-POSTAL-CODE TO CUSTOMER-TABLE.CUST-POSTAL-CODE MOVE INPUT-COUNTRY TO CUSTOMER-TABLE.CUST-COUNTRY INSERT INTO CUSTOMER-TABLE CUST-ID, CUST-COMPANY-NAME, CUST-ADDR-LINE1, CUST-ADDR-LINE2, CUST-CITY, CUST-STATE, CUST-POSTAL-CODE, CUST-COUNTRY /* ------------------------------ */ /* set up the SSA database record */ /* ------------------------------ */ MOVE INPUT-COMPANY-NAME TO SSA-NAME3-TABLE.SSA-NAME3-CUST-NAME MOVE CUSTOMER-TABLE.CUST-ID TO SSA-NAME3-TABLE.CUST-ID STRING CUSTOMER-TABLE.CUST-ADDR-LINE1 CUSTOMER-TABLE.CUST-ADDR-LINE2 INTO SSA-NAME3-TABLE.SSA-NAME3-CUST-STREET STRING CUSTOMER-TABLE.CUST-CITY CUSTOMER-TABLE.CUST-STATE CUSTOMER-TABLE.CUST-COUNTRY INTO SSA-NAME3-TABLE.SSA-NAME3-CUST-LOCALITY MOVE CUSTOMER-TABLE.CUST-POSTAL-CODE TO SSA-NAME3-TABLE.CUST-POSTAL-CODE /* ---------------------------------------- */ /* move each SSA key to the SSA record and */ /* insert to the SSA Table */ /* ---------------------------------------- */ MOVE 1 TO SSA-NAME3-KEYS-STACK-I WHILE SSA-NAME3-KEYS-STACK-I <= SSA-NAME3-KEYS-COUNT MOVE SSA-NAME3-KEY (SSA-NAME3-KEYS-STACK-I) TO SSA-NAME3-CUST-KEY INSERT INTO SSA-NAME3-TABLE SSA-NAME3-CUST-KEY, CUST-ID, SSA-NAME3-CUST-NAME, SSA-NAME3-CUST-STREET, SSA-NAME3-CUST-LOCALITY, CUST-POSTAL-CODE, CUST-BIRTH-DATE. ADD 1 TO SSA-NAME3-KEYS-STACK-I END-WHILE COMMIT END-DEFINE /*------------------------------*/ DEFINE SUBROUTINE SSA-NAME3-ERROR-ABORT /*------------------------------*/ DISPLAY ’SSA ERROR:’ SSA-NAME3-RESPONSE-CODE STOP END-DEFINE /*------------------------------------------------------------------------ */ /* SEARCH & MATCH EXAMPLE 3 */ /* */ /* Purpose: Read a file of new customer transactions and check */ /* if there is a suspicion that they already exist on */ /* the customer db. If so, print an exception report, */ /* otherwise add the new customer to the database. */ /* Uses 8 byte SSA keys. */ /* Description: Read an input sequential file of new customer */ /* transactions. For each record, Call NAMESET with */ /* the company name to get the search ranges then */ /* retrieve the candidate records from the db table. */ /* For each candidate record returned, MATCH it */ /* against the input data. If its accepted as a match */ /* print it to a report of suspect matches. If no */ /* match is found, add the record to the customer and */ /* SSA db tables. */ /* Pre-requisites: 1. Requires the COMPANY Algorithm to be customized */ /* and generated as part of the SSA Service Group */ /* 2. Requires a Matching Scheme to be customized */ /* and generated as part of the SSA Service Group */ /* (in this code we call it COMPADDR) */ /* 3. Requires access to the executable SSA Service */ /* Group in the environment where the program is */ /* to run. */ /* 4. Requires the SSA database table to be loaded */ /* with the SSA 8 byte character Keys. */ /* */ /*------------------------------------------------------------------------ */ /****** DATABASE DEFINITIONS ******/ SSA-NAME3-TABLE /* SSA Key db table */ SSA-NAME3-CUST-KEY CHAR(5) CUST-ID CHAR(10) SSA-NAME3-CUST-NAME CHAR(100) SSA-NAME3-CUST-STREET CHAR(80) SSA-NAME3-CUST-LOCALITY CHAR(45) CUST-POSTAL-CODE CHAR(8) CUSTOMER-TABLE /* customer db table */ CUST-ID CHAR(10) CUST-COMPANY-NAME CHAR(100) CUST-ADDR-LINE1 CHAR(40) CUST-ADDR-LINE2 CHAR(40) CUST-CITY CHAR(20) CUST-STATE CHAR(3) CUST-POSTAL-CODE CHAR(8) CUST-COUNTRY CHAR(20) /****** FILE DEFINITIONS ******/ NEW-CUSTOMER-FILE NEW-COMPANY-NAME CHAR(100) NEW-ADDR-LINE1 CHAR(40) NEW-ADDR-LINE2 CHAR(40) NEW-CITY CHAR(20) NEW-STATE CHAR(3) NEW-POSTAL-CODE CHAR(8) NEW-COUNTRY CHAR(20) /****** VARIABLE DEFINITIONS ******/ /*** SSA NAMESET PARAMETERS ***/ SSA-NAME3-NAMESET-SERVICE CHAR(8) VALUE ’NAMESETC’ /* the NAMESET Service name */ /* must be defined in the */ /* Algorithm Definition */ SSA-NAME3-NAMESET-FUNCTION CHAR(100) VALUE ’*NEG,FULLSEARCH,PROBESWORD*’ /* ’PROBESWORD’ generates */ /* search probes for each */ /* word in the name. */ /* ’NEG,FULLSEARCH’ generates */ /* negative search ranges for */ /* all combinations of two */ /* words in the name. */ SSA-NAME3-NAME-IN CHAR(100) /* SSA-NAME3-NAME-IN & */ /* SSA-NAME3-NAME-CLEAN must */ /* be the same length as */ /* specified in the */ /* Algorithm NAME-LENGTH */ SSA-NAME3-NAME-CLEAN CHAR(100) /* parameter. */ SSA-NAME3-RESPONSE-CODE CHAR(20) REDEFINE SSA-NAME3-RESPONSE-CODE SSA-NAME3-ERROR-NUMBER CHAR(2) SSA-NAME3-ERROR-REASON CHAR(2) SSA-NAME3-ERROR-MODULE CHAR(2) SSA-NAME3-ERROR-SEVERITY CHAR(1) SSA-NAME3-ERROR-UNUSED CHAR(3) SSA-NAME3-SECONDARY-RC CHAR(10) SSA-NAME3-WORDS-STACK /* SSA-NAME3-WORDS-STACK must */ SSA-NAME3-WORDS-COUNT NUM(2) /* be large enough to cater */ SSA-NAME3-WORDS OCCURS 8 TIMES /* for the number of entries */ SSA-NAME3-WORD CHAR(24) /* defined in the Algorithm */ SSA-NAME3-WORD-TYPE CHAR(2) /* WORDS-STACK-SIZE parameter */ SSA-NAME3-WORD-CATEGORY CHAR(2) SSA-NAME3-ORIGINAL-INIT CHAR(1) FILLER CHAR(3) SSA-NAME3-KEYS-STACK /* SSA-NAME3-KEYS-STACK must */ SSA-NAME3-KEYS-COUNT NUM(2) /* be large enough to cater */ SSA-NAME3-KEYS OCCURS 20 TIMES /* for the number of entries */ SSA-NAME3-KEY CHAR(8) /* defined in the Algorithm */ SSA-NAME3-KEY-TYPE CHAR(2) /* KEYS-STACK-SIZE parameter */ SSA-NAME3-SEARCH-TABLE /* SSA-NAME3-SEARCH-TABLE */ SSA-NAME3-PREFERRED-KEY CHAR(8) /* must be large enough */ SSA-NAME3-SEARCH-RANGES OCCURS 21 TIMES /* to cater for the */ SSA-NAME3-KEY-FROM CHAR(8) /* number of entries */ SSA-NAME3-KEY-TO CHAR(8) /* defined in the */ SSA-NAME3-RANGE-DEPTH CHAR(2) /* Algorithm */ SSA-NAME3-RANGE-SCALE CHAR(2) /* SEARCH-TABLE-SIZE */ SSA-NAME3-RANGE-CONTENTS CHAR(2) /* parameter */ SSA-NAME3-RANGE-KEY-TYPE CHAR(2) SSA-NAME3-RANGE-TYPE CHAR(1) SSA-NAME3-RANGE-SEQUENCE CHAR(2) FILLER CHAR(11) SSA-NAME3-CATEGORIES CHAR(20) SSA-NAME3-WORK-AREA CHAR(99999) /* to check if the */ REDEFINE SSA-NAME3-WORK-AREA /* WORK-AREA is large */ SSA-NAME3-WORK-FIRST CHAR(42) /* enough, run a TestBed */ SSA-NAME3-EXTENDED-RC CHAR(20) /* NAMESET & MATCH call */ /* and check the WSIZE= */ /* value. */ SSA-NAME3-WORK-AREA-SIZE CHAR(6) VALUE ’099999’ /* zoned numeric value */ /* equal to the Work-area */ /* size. Only checked if */ /* PASSING- WORKAREA-SIZE */ /* specified in the */ /* Service Group. */ SSA-NAME3-WORK-REST CHAR(99931) SSA-NAME3-DUMMY CHAR(1) /**** SSA MATCH PARAMETERS ****/ SSA-NAME3-MATCH-SERVICE CHAR(8) VALUE ’MATCH’ /* is always MATCH */ SSA-NAME3-MATCH-FUNCTION CHAR(32) VALUE ’*LIMIT=90,VERBOSE*’ /* if a record scores */ /* 90 or above, return */ /* a Result of */ /* RULING=A (accept) */ SSA-NAME3-EXTRACT-FUNCTION CHAR(32) VALUE ’*EXTRACT=RULING*’ /* extract the ruling */ /* value from the */ /* Result of a */ /* previous MATCH call */ SSA-NAME3-MATCH-SCHEME CHAR(8) VALUE ’COMPADDR’ /* the SCHEME name must be */ /* defined in the Scheme */ /* definition file */ SSA-NAME3-MATCH-RESULT CHAR(1000) SSA-NAME3-EXTRACT-RESULT CHAR(1) SSA-NAME3-MATCH-SEARCH-DATA /* Search Data and File */ SSA-NAME3-MATCH-SEARCH-NAME CHAR(100) /* Data definitions must */ SSA-NAME3-MATCH-SEARCH-STREET CHAR(80) /* match the layout of the */ /* Scheme being used (i.e. */ SSA-NAME3-MATCH-FILE-DATA /* SSA-NAME3-SCHEME-NAME) */ SSA-NAME3-MATCH-FILE-NAME CHAR(100) /* Check the field offsets */ SSA-NAME3-MATCH-FILE-STREET CHAR(80) /* & lengths */ SSA-NAME3-MATCH-MTBL CHAR(147) REDEFINE SSA-NAME3-MATCH-MTBL SSA-NAME3-MTBL-HEADER CHAR(25) SSA-NAME3-MTBL-METHOD-ENTRY OCCURS 2 SSA-NAME3-METHOD-NAME CHAR(8) SSA-NAME3-METHOD-EP CHAR(8) SSA-NAME3-METHOD-ALG CHAR(8) SSA-NAME3-FIELD-OFFSET CHAR(5) SSA-NAME3-FIELD-LENGTH CHAR(3) SSA-NAME3-METHOD-RESP CHAR(20) SSA-NAME3-METHOD-SCORE CHAR(3) SSA-NAME3-METHOD-WEIGHT CHAR(3) SSA-NAME3-METHOD-WGTMOD CHAR(3) /***** OTHER VARIABLES ******/ TRANSACTION-REPORT-LINE TRAN-REPORT-COMPANY-NAME CHAR(50) TRAN-REPORT-ADDRESS CHAR(50) CUSTOMER-REPORT-LINE FILLER CHAR(10) CUST-REPORT-COMPANY-NAME CHAR(50) CUST-REPORT-ADDRESS CHAR(50) CUST-REPORT-CUST-ID CHAR(10) CUST-REPORT-SCORE NUM(3) CANDIDATE-ARRAY CANDIDATE-CUST-ID CHAR(10) OCCURS 999 SSA-NAME3-KEYS-STACK-I NUM(2) SSA-NAME3-STAB-I NUM(2) CANDIDATE-I NUM(4) MATCH-C NUM(3) /****** PROGRAM LOGIC ******/ /* --------------------------------------------------------- */ /* initialize SSA parameters and open input transaction file */ /* --------------------------------------------------------- */ INITIALIZE SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES. OPEN INPUT NEW-CUSTOMER-FILE /* ------------------------------------------------- */ /* program loop to control reading of the input file */ /* ------------------------------------------------- */ WHILE NOT END-OF-FILE INITIALIZE SSA-NAME3-STAB-I, CANDIDATE-I, SCREEN-I, MATCH-CUST-ID /* ----------------------- */ /* read transaction record */ /* ----------------------- */ READ NEW-CUSTOMER-FILE RECORD IF END-OF-FILE BREAK END-IF /* -------------------------------------------------------------- */ /* Call NAMESET with the search name to get the search key ranges */ /* -------------------------------------------------------------- */ MOVE NEW-COMPANY-NAME TO SSA-NAME3-NAME-IN MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-NAMESET-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-NAMESET-FUNCTION, SSA-NAME3-NAME-IN, SSA-NAME3-NAME-CLEAN, SSA-NAME3-WORDS-STACK, SSA-NAME3-KEYS-STACK, SSA-NAME3-SEARCH-TABLE, SSA-NAME3-CATEGORIES, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) PERFORM SSA-NAME3-ERROR-CHECK /* ----------------------------------- */ /* set up the search data for MATCHing */ /* ----------------------------------- */ MOVE NEW-COMPANY-NAME TO SSA-NAME3-MATCH-SEARCH-NAME STRING NEW-ADDR-LINE-1, NEW-ADDR-LINE2 INTO SSA-NAME3-MATCH-SEARCH-STREET /* ----------------------------------------------------------- */ /* program loop to control the processing of the search ranges */ /* ----------------------------------------------------------- */ MOVE 1 TO SSA-NAME3-STAB-I WHILE SSA-NAME3-RANGE-CONTENTS (SSA-NAME3-STAB-I) NOT = ’00’ /* ------------------------------------------------ */ /* open cursor for sequential read of SSA key table */ /* ------------------------------------------------ */ DEFINE SSA-NAME3-SEARCH-CANDIDATE CURSOR SELECT CUST-ID, SSA-NAME3-CUST-NAME, CUST-POSTAL-CODE, CUST-BIRTH-DATE FROM SSA-NAME3-TABLE WHERE SSA-NAME3-CUST-KEY >= SSA-NAME3-KEY-FROM (SSA-NAME3-STAB-I) AND SSA-NAME3-CUST-KEY <= SSA-NAME3-KEY-TO (SSA-NAME3-STAB-I) END-DEFINE OPEN SSA-NAME3-SEARCH-CANDIDATE /* ---------------------------------------------------------------- */ /* program loop to control the reading of records from the database */ /* ---------------------------------------------------------------- */ WHILE NOT END-OF-CURSOR FETCH SSA-NAME3-SEARCH-CANDIDATE IF END-OF-CURSOR CLOSE SSA-NAME3-SEARCH-CANDIDATE BREAK END-IF /* ------------------------------------------------------- */ /* check in the candidates array if we have processed this */ /* record in a previous search range and if so don’t */ /* score it again */ /* ------------------------------------------------------- */ IF CANDIDATE-I = 999 /* max number of candidates */ BREAK /* allowed in this program */ END-IF PERFORM CHECK-DUPLICATE-CANDIDATE IF DUPLICATE-CANDIDATE CONTINUE /* go fetch the next record */ END-IF /* ------------------------------- */ /* setup the file data for scoring */ /* ------------------------------- */ MOVE SSA-NAME3-CUST-NAME TO SSA-NAME3-MATCH-FILE-NAME MOVE SSA-NAME3-CUST-STREET TO SSA-NAME3-MATCH-FILE-STREET /* ------------------------------------------------------------- */ /* Call MATCH to score the file record against the search record */ /* ------------------------------------------------------------- */ MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-MATCH-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-MATCH-FUNCTION, SSA-NAME3-MATCH-SCHEME, SSA-NAME3-MATCH-RESULT, SSA-NAME3-MATCH-SEARCH-DATA, SSA-NAME3-MATCH-FILE-DATA, SSA-NAME3-MATCH-MTBL, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) PERFORM SSA-NAME3-ERROR-CHECK /* ------------------------------------------------------- */ /* Call MATCH again to extract the ruling from the result */ /* of the previous MATCH Call. If the record has been */ /* flagged as "accept" (RULING=A), print the record to the */ /* exception report */ /* ------------------------------------------------------- */ MOVE ’90’ TO SSA-NAME3-ERROR-NUMBER CALL ’N3SGUS’ (SSA-NAME3-MATCH-SERVICE, SSA-NAME3-RESPONSE-CODE, SSA-NAME3-EXTRACT-FUNCTION, SSA-NAME3-DUMMY, SSA-NAME3-EXTRACT-RESULT, SSA-NAME3-MATCH-RESULT, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY, SSA-NAME3-WORK-AREA, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY, SSA-NAME3-DUMMY) PERFORM SSA-NAME3-ERROR-CHECK IF SSA-NAME3-EXTRACT-RESULT = ’A’ ADD 1 TO MATCH-C IF MATCH-C = 1 PRINT TRANSACTION-REPORT-LINE END-IF MOVE SSA-NAME3-TABLE.CUST-ID TO CUST-REPORT-CUST-ID MOVE SSA-NAME3-CUST-NAME TO CUST-REPORT-COMPANY-NAME STRING SSA-NAME3-CUST-STREET, SSA-NAME3-CUST-LOCALITY, CUST-POSTAL-CODE INTO CUST-REPORT-ADDRESS MOVE SSA-NAME3-SCORE TO CUST-REPORT-SCORE PRINT CUSTOMER-REPORT-LINE END-IF END-WHILE /* Fetch Candidate Records */ IF CANDIDATE-I = 999 BREAK END-IF ADD 1 TO SSA-NAME3-STAB-I END-WHILE /* NAMESET Search Ranges */ IF CANDIDATE-I = 999 PRINT ’TOO MANY RECORDS FOUND FOR ’ NEW-COMPANY-NAME CONTINUE /* go back and read the next record */ END-IF /* -----------------------------------------------------------*/ /* if no matches found, add the new record to the customer db */ /* -----------------------------------------------------------*/ IF MATCH-C = 0 PERFORM ADD-NEW-CUSTOMER END-IF END-WHILE /* Input Search Data */ CLOSE NEW-CUSTOMER-FILE /*----------------------------------------*/ DEFINE SUBROUTINE CHECK-DUPLICATE-CANDIDATE /*----------------------------------------*/ MOVE FALSE TO DUPLICATE-CANDIDATE IF CANDIDATE-I > 0 INITIALIZE WORK-I WHILE WORK-I <= CANDIDATE-I ADD 1 TO WORK-I IF CUST-ID = CANDIDATE-CUST-ID (WORK-I) MOVE TRUE TO DUPLICATE-CANDIDATE BREAK END-IF END-WHILE END-IF IF NOT DUPLICATE-CANDIDATE ADD 1 TO CANDIDATE-I MOVE CUST-ID TO CANDIDATE-CUST-ID (CANDIDATE-I) END-IF END-DEFINE /* -------------------------- */ DEFINE SUBROUTINE DISPLAY-SCREEN /* -------------------------- */ OUTPUT SCREEN-ARRAY IF ESCAPE-SELECTED BREAK END-IF /* ------------------------------------------- */ /* let the user select a match from the screen */ /* ------------------------------------------- */ INITIALIZE WORK-I WHILE WORK-I <= SCREEN-I ADD 1 TO WORK-I IF SCREEN-SELECT (WORK-I) MOVE SCREEN-CUST-ID TO MATCH-CUST-ID BREAK END-IF END-WHILE END-DEFINE /* ---------------------------- */ DEFINE SUBROUTINE ADD-NEW-CUSTOMER /* ---------------------------- */ INITIALIZE CUSTOMER-TABLE, SSA-NAME3-TABLE /* ------------------------------ */ /* set up the customer record */ /* ------------------------------ */ ASSIGN UNIQUE ID TO CUSTOMER-TABLE.CUST-ID MOVE INPUT-COMPANY-NAME TO CUSTOMER-TABLE.CUST-COMPANY-NAME MOVE INPUT-ADDR-LINE1 TO CUSTOMER-TABLE.CUST-ADDR-LINE1 MOVE INPUT-ADDR-LINE2 TO CUSTOMER-TABLE.CUST-ADDR-LINE2 MOVE INPUT-CITY TO CUSTOMER-TABLE.CUST-CITY MOVE INPUT-STATE TO CUSTOMER-TABLE.CUST-STATE MOVE INPUT-POSTAL-CODE TO CUSTOMER-TABLE.CUST-POSTAL-CODE MOVE INPUT-COUNTRY TO CUSTOMER-TABLE.CUST-COUNTRY INSERT INTO CUSTOMER-TABLE CUST-ID, CUST-COMPANY-NAME, CUST-ADDR-LINE1, CUST-ADDR-LINE2, CUST-CITY, CUST-STATE, CUST-POSTAL-CODE, CUST-COUNTRY /* ------------------------------ */ /* set up the SSA database record */ /* ------------------------------ */ MOVE INPUT-COMPANY-NAME TO SSA-NAME3-TABLE.SSA-NAME3-CUST-NAME MOVE CUSTOMER-TABLE.CUST-ID TO SSA-NAME3-TABLE.CUST-ID STRING CUSTOMER-TABLE.CUST-ADDR-LINE1 CUSTOMER-TABLE.CUST-ADDR-LINE2 INTO SSA-NAME3-TABLE.SSA-NAME3-CUST-STREET STRING CUSTOMER-TABLE.CUST-CITY CUSTOMER-TABLE.CUST-STATE CUSTOMER-TABLE.CUST-COUNTRY INTO SSA-NAME3-TABLE.SSA-NAME3-CUST-LOCALITY MOVE CUSTOMER-TABLE.CUST-POSTAL-CODE TO SSA-NAME3-TABLE.CUST-POSTAL-CODE /* ---------------------------------------- */ /* move each SSA key to the SSA record and */ /* insert to the SSA Table */ /* ---------------------------------------- */ MOVE 1 TO SSA-NAME3-KEYS-STACK-I WHILE SSA-NAME3-KEYS-STACK-I <= SSA-NAME3-KEYS-COUNT MOVE SSA-NAME3-KEY (SSA-NAME3-KEYS-STACK-I) TO SSA-NAME3-CUST-KEY INSERT INTO SSA-NAME3-TABLE SSA-NAME3-CUST-KEY, CUST-ID, SSA-NAME3-CUST-NAME, SSA-NAME3-CUST-STREET, SSA-NAME3-CUST-LOCALITY, CUST-POSTAL-CODE, CUST-BIRTH-DATE. ADD 1 TO SSA-NAME3-KEYS-STACK-I END-WHILE COMMIT END-DEFINE /*------------------------------*/ DEFINE SUBROUTINE SSA-NAME3-ERROR-CHECK /*------------------------------*/ IF SSA-NAME3-ERROR-NUMBER NOT = ’00’ IF SSA-NAME3-ERROR-NUMBER >= ’90’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY >= ’2’ PERFORM SSA-NAME3-ERROR-ABORT END-IF IF SSA-NAME3-ERROR-SEVERITY = ’1’ DISPLAY "SSA WARNING: " SSA-NAME3-RESPONSE-CODE END-IF END-IF END-DEFINE /*------------------------------*/ DEFINE SUBROUTINE SSA-NAME3-ERROR-ABORT /*------------------------------*/ PRINT ’SSA ERROR:’ SSA-NAME3-RESPONSE-CODE STOP END-DEFINE