Skip to main content

Initializing Data (BANKDATA)

The BANKDATA program is responsible for initializing and populating customer and account data in a simulated banking application. The program achieves this by setting up initial parameters, validating input, generating random customer data, and performing database operations to insert and delete records. The program also handles file operations and ensures data integrity through various validation and commit processes.

The BANKDATA program starts by initializing parameters and validating input. It then generates random customer data, including names, addresses, birth dates, and credit scores. The program writes this data to the CUSTOMER and ACCOUNT datastores, performs necessary database operations, and commits the records to ensure data integrity. Finally, it closes the files and logs the operations for tracking purposes.

Here is a high level diagram of the program:

Setup Initialization


Starting the PREMIERE Section

First, the PREMIERE section starts by setting a message 'Starting BANKDATA' to the TIMESTAMP-FUNCTION variable. This is followed by a call to the TIMESTAMP paragraph to log the start time.

       PREMIERE SECTION.
A010.
MOVE 'Starting BANKDATA'
to TIMESTAMP-FUNCTION
perform TIMESTAMP


Logging the Start Time

The TIMESTAMP paragraph logs the current time by calling the 'CEEGMT' and 'CEEDATM' functions to get the current GMT time and format it. This helps in tracking when the PREMIERE section started.

       TIMESTAMP SECTION.
CALL 'CEEGMT' USING BY REFERENCE gmt-lilian
BY REFERENCE gmt-seconds
BY REFERENCE fc

***
*** Move gmt to an integer so that we don't round up
*** in the division
***
MOVE gmt-seconds TO period-next-f.
COMPUTE period-next = period-next-f.

***
*** Convert back into text
***
MOVE 14 TO datm-length.
MOVE 'YYYYMMDDHHMISS' TO datm-format.
CALL 'CEEDATM' USING BY REFERENCE period-next
BY REFERENCE datm-picture
BY REFERENCE datm-conv
BY REFERENCE fc.


Initializing Arrays

Next, a message 'About to initialise arrays' is displayed. The INITIALISE-ARRAYS paragraph is then performed to set up various arrays used in the program.

      * Initialise the arrays
*
D DISPLAY 'About to initialise arrays'.
PERFORM INITIALISE-ARRAYS.


Setting Up Arrays

The INITIALISE-ARRAYS paragraph initializes several arrays with predefined values. This includes setting up titles, forenames, surnames, street names, towns, account types, and interest rates. This setup is crucial for the subsequent operations in the program.

       INITIALISE-ARRAYS SECTION.
IA010.

MOVE TITLE-ALPHABET TO TITLE-WORDS.

MOVE 50 TO FORENAMES-CNT.

MOVE 'Michael' TO FORENAME(01).
MOVE 'Will' TO FORENAME(02).
MOVE 'Geoff' TO FORENAME(03).
MOVE 'Chris' TO FORENAME(04).
MOVE 'Dave' TO FORENAME(05).
MOVE 'Luke' TO FORENAME(06).
MOVE 'Adam' TO FORENAME(07).
MOVE 'Giuseppe' TO FORENAME(08).
MOVE 'James' TO FORENAME(09).
MOVE 'Jon' TO FORENAME(10).
MOVE 'Andy' TO FORENAME(11).
MOVE 'Lou' TO FORENAME(12).
MOVE 'Robert' TO FORENAME(13).
MOVE 'Sam' TO FORENAME(14).

Parameter Handling and Validation


Get Parameters

First, the parameters are extracted from the input string PARM using the UNSTRING command. These parameters include START-KEY, END-KEY, STEP-KEY, and RANDOM-SEED. This step is crucial for setting up the range and steps for customer data processing.

      * Get the parameters
*
UNSTRING PARM(1:PARM-LENGTH)
DELIMITED BY SPACE OR ','
INTO START-KEY
END-KEY
STEP-KEY
RANDOM-SEED.


Display Input Parameters

Next, the extracted parameters are displayed for verification. This helps in ensuring that the correct values have been parsed and are ready for further processing.

      D    DISPLAY 'INPUT PARMS ARE: START-KEY=' START-KEY
D ' END-KEY=' END-KEY ' STEP-KEY=' STEP-KEY
D ' RANDOM-SEED=' RANDOM-SEED '


Validate Parameters

Then, the parameters are validated. If END-KEY is less than START-KEY, an error message is displayed and the process is terminated. Similarly, if STEP-KEY is zero, an error message is displayed and the process is terminated. These validations ensure that the input parameters are logical and prevent any erroneous operations.

           IF END-KEY < START-KEY
MOVE 12 TO RETURN-CODE
DISPLAY 'Final customer number cannot be smaller than '
'first customer number'
GOBACK
END-IF
IF step-key = zero
MOVE 12 TO RETURN-CODE
DISPLAY 'Gap between customers cannot be zero'
GOBACK
END-IF


Get Today's Date

Moving to the next step, the current date is fetched and stored as an integer. This is done by performing the GET-TODAYS-DATE section.

      * Get today's date and store it as an INTEGER
*
PERFORM GET-TODAYS-DATE.


GET-TODAYS-DATE

The GET-TODAYS-DATE section retrieves the current date using the CURRENT-DATE function and converts it into an integer format. This integer date is then stored in WS-TODAY-INT for further use in the program.

       GET-TODAYS-DATE SECTION.
GTD010.
D DISPLAY 'IN GET-TODAYS-DATE SECTION'.

MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-DATA.

MOVE WS-CURRENT-DATE-DATA (1:8) TO WS-CURRENT-DATE-9.

COMPUTE WS-TODAY-INT =
FUNCTION INTEGER-OF-DATE (WS-CURRENT-DATE-9).

GTD999.
EXIT.

Interim Summary

So far, we saw how the program initializes by setting up timestamps and arrays, and then handles and validates input parameters. Now, we will focus on the process of deleting rows from the DB2 tables, including the ACCOUNT and CONTROL tables, and ensuring the deletions are committed.

Date and Random Seed Initialization


Display 'About to delete DB2 rows'

First, we display a message indicating that the process of deleting DB2 rows is about to begin. This helps in tracking the flow of operations.

      D    DISPLAY 'About to delete DB2 rows'.


Delete rows from ACCOUNT table

Moving to the DELETE-DB2-ROWS section, we start by deleting rows from the ACCOUNT table where the ACCOUNT_SORTCODE matches the provided SortCode. This ensures that only relevant rows are deleted.

       DELETE-DB2-ROWS SECTION.
DBR010.
*
* Delete the ACCOUNT table data
*
MOVE SORTCODE TO HV-ACCOUNT-SORT-CODE.
MOVE 'Deleting from ACCOUNT table'
to TIMESTAMP-FUNCTION
perform TIMESTAMP
EXEC SQL
DELETE FROM ACCOUNT
WHERE ACCOUNT_SORTCODE = :HV-ACCOUNT-SORT-CODE
END-EXEC.


Check SQL code for ACCOUNT table

Next, we check the SQL code to ensure the deletion was successful. If the SQL code is not OK (0) or NOTFND (+100), we handle the error by displaying an appropriate message and setting the return code.

      * Check the SQL code if it was NOT OK (0) or NOTFND (+100)
* then abend
*
MOVE 'Deleting from ACCOUNT table COMPLETE'
to TIMESTAMP-FUNCTION
perform TIMESTAMP
IF SQLCODE NOT = +100 AND
SQLCODE NOT = 0

MOVE SQLCODE TO DISP-SQLCD
IF SQLCODE < 0
MOVE '-' TO DISP-SIGN
ELSE
MOVE '+' TO DISP-SIGN
END-IF
EVALUATE TRUE
WHEN SQLERRD(3) EQUAL 13172878
MOVE 'TIMEOUT (00C900E)' TO DISP-REASON-CODE
WHEN SQLERRD(3) EQUAL 13172872
MOVE 'DEADLOCK (00C9088)' TO DISP-REASON-CODE
WHEN OTHER


Delete rows from CONTROL table - ACCOUNT-LAST

Then, we delete rows from the CONTROL table where the CONTROL_NAME is constructed using the SortCode and ACCOUNT-LAST. This step ensures that related control data is also removed.

      * Delete the CONTROL table data
*
MOVE SPACES TO HV-CONTROL-NAME
STRING SORTCODE DELIMITED BY SIZE
'-' DELIMITED BY SIZE
'ACCOUNT-LAST' DELIMITED BY SIZE
INTO HV-CONTROL-NAME

MOVE 'Deleting from CONTROL table'
to TIMESTAMP-FUNCTION.

PERFORM TIMESTAMP.

EXEC SQL
DELETE FROM CONTROL
WHERE CONTROL_NAME = :HV-CONTROL-NAME
END-EXEC.


Check SQL code for CONTROL table - ACCOUNT-LAST

We again check the SQL code to ensure the deletion from the CONTROL table was successful. Similar to the previous check, we handle any errors by displaying messages and setting the return code.

      *    Check the SQL code if it was NOT OK (0) or NOTFND (+100)
* then abend
*
MOVE 'Deleting from CONTROL table COMPLETE'
to TIMESTAMP-FUNCTION.

PERFORM TIMESTAMP.

IF SQLCODE NOT = +100 AND
SQLCODE NOT = 0

MOVE SQLCODE TO DISP-SQLCD
IF SQLCODE < 0
MOVE '-' TO DISP-SIGN
ELSE
MOVE '+' TO DISP-SIGN
END-IF
EVALUATE TRUE
WHEN SQLERRD(3) EQUAL 13172878
MOVE 'TIMEOUT (00C900E)' TO DISP-REASON-CODE
WHEN SQLERRD(3) EQUAL 13172872


Delete rows from CONTROL table - ACCOUNT-COUNT

Next, we delete rows from the CONTROL table where the CONTROL_NAME is constructed using the SortCode and ACCOUNT-COUNT. This step ensures that all related control data is removed.

      *
MOVE SPACES TO HV-CONTROL-NAME
STRING SORTCODE DELIMITED BY SIZE
'-' DELIMITED BY SIZE
'ACCOUNT-COUNT' DELIMITED BY SIZE
INTO HV-CONTROL-NAME

MOVE 'Deleting from CONTROL table'
to TIMESTAMP-FUNCTION.

PERFORM TIMESTAMP.

EXEC SQL
DELETE FROM CONTROL
WHERE CONTROL_NAME = :HV-CONTROL-NAME
END-EXEC.


Check SQL code for CONTROL table - ACCOUNT-COUNT

We perform another SQL code check to ensure the deletion from the CONTROL table was successful. Any errors are handled similarly by displaying messages and setting the return code.

      *    Check the SQL code if it was NOT OK (0) or NOTFND (+100)
* then abend
*
MOVE 'Deleting from CONTROL table COMPLETE'
to TIMESTAMP-FUNCTION.

PERFORM TIMESTAMP.

IF SQLCODE NOT = +100 AND
SQLCODE NOT = 0

MOVE SQLCODE TO DISP-SQLCD
IF SQLCODE < 0
MOVE '-' TO DISP-SIGN
ELSE
MOVE '+' TO DISP-SIGN
END-IF
EVALUATE TRUE
WHEN SQLERRD(3) EQUAL 13172878
MOVE 'TIMEOUT (00C900E)' TO DISP-REASON-CODE
WHEN SQLERRD(3) EQUAL 13172872


Commit work

Finally, we commit the work to ensure that all deletions are saved and the database is updated accordingly.

           EXEC SQL
COMMIT WORK
END-EXEC.


Display 'Back from delete DB2 rows'

After completing the deletions and committing the work, we display a message indicating that the process of deleting DB2 rows is complete. This helps in tracking the flow of operations.

      D    DISPLAY 'Back from delete DB2 rows'.

File Opening

This is the next section of the flow.


Opening the Customer File

First, the code attempts to open the CUSTOMER-FILE for output. This is a crucial step as it prepares the file for subsequent operations such as writing customer data.

           OPEN OUTPUT CUSTOMER-FILE.


Handling File Open Errors

Next, the code checks if the CUSTOMER-VSAM-STATUS is not equal to '00', which indicates an error in opening the file. If an error is detected, it displays an error message with the status code, sets the RETURN-CODE to 12 to indicate an error, and performs the PROGRAM-DONE routine to handle the termination of the program.

           IF CUSTOMER-VSAM-STATUS NOT EQUAL '00' THEN
DISPLAY 'Error opening CUSTOMER file, status='
CUSTOMER-VSAM-STATUS
MOVE 12 TO RETURN-CODE
PERFORM PROGRAM-DONE
END-IF.

Data Population Loop


Initialize Customer Data

First, we initialize the customer data by setting up the timestamp, commit count, and customer/account numbers. This sets the stage for generating new customer records.

      * Populate the CUSTOMER file
*
MOVE 'Populating Customer + Account files'
to TIMESTAMP-FUNCTION
perform TIMESTAMP
MOVE ZERO TO COMMIT-COUNT
MOVE ZERO TO LAST-CUSTOMER-NUMBER NUMBER-OF-CUSTOMERS
MOVE ZERO TO LAST-ACCOUNT-NUMBER NUMBER-OF-ACCOUNTS


Generate Random Customer Data

Next, we loop through a range of keys to generate customer data. For each key, we initialize the customer record and set a unique customer number.

           PERFORM TEST BEFORE
VARYING NEXT-KEY FROM START-KEY BY STEP-KEY
UNTIL NEXT-KEY > END-KEY

INITIALIZE CUSTOMER-RECORD IN CUSTOMER-RECORD-STRUCTURE

SET CUSTOMER-EYECATCHER-VALUE TO TRUE

MOVE NEXT-KEY TO CUSTOMER-NUMBER
MOVE NEXT-KEY TO LAST-CUSTOMER-NUMBER
ADD 1 TO NUMBER-OF-CUSTOMERS GIVING NUMBER-OF-CUSTOMERS


Generate Random Address

Then, we generate random values for the customer's title, forenames, initials, surname, house number, street names, and town. These values are combined to form the customer's name and address.


D DISPLAY 'Generating data for customer ' customer-number

COMPUTE TITLE-NUMBER = ((36 - 1)
* FUNCTION RANDOM) + 1
COMPUTE FORENAMES-PTR = ((FORENAMES-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE INITIALS-PTR = ((INITIALS-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE SURNAMES-PTR = ((SURNAMES-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE HOUSE-NUMBER = (99
* FUNCTION RANDOM) + 1
COMPUTE STREET-NAME-T-PTR = ((STREET-NAME-T-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE STREET-NAME-R-PTR = ((STREET-NAME-R-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE TOWN-PTR = ((TOWN-COUNT - 1)
* FUNCTION RANDOM) + 1

MOVE SPACES TO CUSTOMER-NAME


Generate Random Birth Date

Moving to the next step, we generate a random birth date for the customer, ensuring the date is within a realistic range.


COMPUTE CUSTOMER-BIRTH-DAY = ((28 - 1)
* FUNCTION RANDOM) + 1
COMPUTE CUSTOMER-BIRTH-MONTH = ((12 - 1)
* FUNCTION RANDOM) + 1
COMPUTE CUSTOMER-BIRTH-YEAR = ((2000 - 1900)
* FUNCTION RANDOM) + 1900


Generate Random Credit Score

We then generate a random credit score for the customer, which will be used in later processes.


MOVE SORTCODE TO
CUSTOMER-SORTCODE


COMPUTE CUSTOMER-CREDIT-SCORE = ((999 - 1)
* FUNCTION RANDOM) + 1


Generate Review Date

Next, we generate a random review date for the customer's credit score, ensuring it falls within 1 to 21 days from the current date. This date is then formatted and stored in the customer record.


*
* Generate the random credit score review date. This
* should be a date between 1 and 21 days from today
*

COMPUTE WS-REVIEW-DATE-ADD = ((21 - 1)
* FUNCTION RANDOM) + 1

COMPUTE WS-NEW-REVIEW-DATE-INT =
WS-TODAY-INT + WS-REVIEW-DATE-ADD

*
* Convert the integer date back to YYYYMMDD format
* and store on the CUSTOMER record
*
COMPUTE WS-NEW-REVIEW-YYYYMMDD = FUNCTION
DATE-OF-INTEGER (WS-NEW-REVIEW-DATE-INT)

MOVE WS-NEW-REVIEW-YYYYMMDD(1:4) TO
CUSTOMER-CS-REVIEW-YEAR


Write Customer Record

We write the populated customer record to the CUSTOMER datastore.


WRITE CUSTOMER-RECORD-STRUCTURE


Check Write Status

We check the status of the write operation. If there is an error, we display an error message and perform the program termination routine.


IF CUSTOMER-VSAM-STATUS NOT EQUAL '00' THEN
DISPLAY 'Error writing to VSAM file, status='
CUSTOMER-VSAM-STATUS
MOVE 12 TO RETURN-CODE
PERFORM PROGRAM-DONE
END-IF


Populate Account Data

Having written the customer data, we now use some of this information to populate related data in the ACCOUNT datastore.

      *
* Having written out to the CUSTOMER datastore we now need to
* use some of this information to populate related data on
* on the ACCOUNT datastore.
*

PERFORM DEFINE-ACC


Commit Records

Finally, we increment the commit count and commit the records to the database every 1,000 records to ensure data integrity.


ADD 1 TO COMMIT-COUNT GIVING COMMIT-COUNT
IF COMMIT-COUNT > 1000
D DISPLAY 'Commit every 1,000 records or so'
EXEC SQL
COMMIT WORK
END-EXEC
MOVE ZERO TO COMMIT-COUNT
END-IF

Post-Population Operations

This is the next section of the flow.


Initialize Customer Control Number

First, the customer control number is initialized to '9999999999'. This sets a default value for the customer control record.

           MOVE '9999999999' TO CUSTOMER-CONTROL-NUMBER


Set Control Eyecatcher

Moving to the next step, the control eyecatcher is set to true. This is likely used as a flag to indicate that the customer control record is active.

           SET CUSTOMER-CONTROL-EYECATCHER-V TO TRUE


Display Write Message

Next, a message is displayed indicating that the customer control record is about to be written. This is useful for logging and debugging purposes.

      D    DISPLAY 'ABOUT TO WRITE CUSTOMER-CONTROL-RECORD'


Move Customer Control Record

Then, the customer control record is moved to the customer record structure. This prepares the data for writing to the file.

           MOVE CUSTOMER-CONTROL-RECORD
TO CUSTOMER-RECORD IN CUSTOMER-RECORD-STRUCTURE


Write Customer Record Structure

The customer record structure is written to the file. This step persists the customer control record.

           WRITE CUSTOMER-RECORD-STRUCTURE


Check VSAM Status

If the VSAM status is not '00', an error message is displayed, the return code is set to 12, and the program done routine is performed. This handles any errors that occur during the write operation.

           IF CUSTOMER-VSAM-STATUS NOT EQUAL '00' THEN
DISPLAY 'Error writing CUSTOMER-CONTROL-RECORD file'
', status=' CUSTOMER-VSAM-STATUS
MOVE 12 TO RETURN-CODE
PERFORM PROGRAM-DONE
END-IF.


Move Spaces to Control Name

Moving to the next part, spaces are moved to the control name. This initializes the control name variable.

           MOVE SPACES TO HV-CONTROL-NAME


Move Last Account Number

The last account number is moved to the control value number. This sets the value to be stored in the control record.

           MOVE LAST-ACCOUNT-NUMBER TO HV-CONTROL-VALUE-NUM


Move Spaces to Control Value String

Spaces are moved to the control value string. This initializes the control value string variable.

           MOVE SPACES TO HV-CONTROL-VALUE-STR


Create Control Name String

A string is created for the control name by concatenating the sort code, a hyphen, and ACCOUNT-LAST. This forms the control name for the last account number.

           STRING SORTCODE DELIMITED BY SIZE
'-' DELIMITED BY SIZE
'ACCOUNT-LAST' DELIMITED BY SIZE
INTO HV-CONTROL-NAME


Insert Last Account Control Record

An SQL insert statement is executed to insert the last account control record into the control table. This stores the last account number in the database.

           EXEC SQL
INSERT INTO CONTROL
(CONTROL_NAME,
CONTROL_VALUE_NUM,
CONTROL_VALUE_STR
)
VALUES (:HV-CONTROL-NAME,
:HV-CONTROL-VALUE-NUM,
:HV-CONTROL-VALUE-STR
)
END-EXEC.


Check SQLCODE

If the SQLCODE is not zero, an error message is displayed. This handles any errors that occur during the insert operation.

           IF SQLCODE IS NOT EQUAL TO ZERO
MOVE SQLCODE TO WS-SQLCODE-DISPLAY
DISPLAY 'Error inserting last account control record '
ws-sqlcode-display
'.'
HV-CONTROL-NAME,
','
HV-CONTROL-VALUE-NUM
END-IF


Move Spaces to Control Name

Moving to the next part, spaces are moved to the control name. This initializes the control name variable for the next insert operation.

           MOVE SPACES TO HV-CONTROL-NAME


Move Number of Accounts

The number of accounts is moved to the control value number. This sets the value to be stored in the control record.

           MOVE NUMBER-OF-ACCOUNTS TO HV-CONTROL-VALUE-NUM


Move Spaces to Control Value String

Spaces are moved to the control value string. This initializes the control value string variable.

           MOVE SPACES TO HV-CONTROL-VALUE-STR


Create Control Name String

A string is created for the control name by concatenating the sort code, a hyphen, and ACCOUNT-COUNT. This forms the control name for the number of accounts.

           STRING SORTCODE DELIMITED BY SIZE
'-' DELIMITED BY SIZE
'ACCOUNT-COUNT' DELIMITED BY SIZE
INTO HV-CONTROL-NAME


Insert Account Count Control Record

An SQL insert statement is executed to insert the account count control record into the control table. This stores the number of accounts in the database.

           EXEC SQL
INSERT INTO CONTROL
(CONTROL_NAME,
CONTROL_VALUE_NUM,
CONTROL_VALUE_STR
)
VALUES (:HV-CONTROL-NAME,
:HV-CONTROL-VALUE-NUM,
:HV-CONTROL-VALUE-STR
)
END-EXEC.


Check SQLCODE

If the SQLCODE is not zero, an error message is displayed. This handles any errors that occur during the insert operation.

           IF SQLCODE IS NOT EQUAL TO ZERO
MOVE SQLCODE TO WS-SQLCODE-DISPLAY
DISPLAY 'Error inserting account count control record '
ws-sqlcode-display
'.'
HV-CONTROL-NAME,
','
HV-CONTROL-VALUE-NUM
END-IF

Closing and Final Timestamp

This is the next section of the flow.


Start Closing Files

This section begins the process of closing the files used in the banking application. It ensures that all files are properly closed after transactions are processed, maintaining data integrity and preventing data loss.

      *
*** Close the files
*


Close BANKDATA File

The BANKDATA file, which contains customer and account information, is closed to ensure that all changes are saved and the file is not left in an open state, which could lead to data corruption.

           CLOSE CUSTOMER-FILE.

MOVE 'Finishing BANKDATA'
to TIMESTAMP-FUNCTION
perform TIMESTAMP.


Close TRANSACTIONS File

The TRANSACTIONS file, which logs all the transactions processed during the session, is closed to ensure that all transaction records are properly saved and the file is secured.


A999.
EXIT.

*


End Closing Files

This marks the end of the file closing process, ensuring that all necessary files have been closed properly, and the system can safely proceed to the next steps or shut down.

      * Finish
*

 

This is an auto-generated document by Swimm 🌊 and has not yet been verified by a human