8.3 银行主文件维护平衡线程序(BKUPD1)
下面是平衡线算法在银行主文件维护中的应用例子。第11行到第20行的文件控制(FILE-CONTROL)节说明我们要处理的3个文件,即交易文件、旧主文件和新主文件,它们都是顺序(QSAM)文件,其记录格式单独列在程序的后面,并给出了每个字段的说明。新主文件和旧主文件的格式是完全一样的,所以我们使用COPY…REPLACING短语来描述它们。第22行到第45行的代码给出了每个文件的记录格式的描述。第27行、第35行和第43行的BLOCK CONTAINS 0 RECORDS表明文件的分区大小(BLOCK SIZE)由运行作业流(JCL)指定。
第61行到第74行的代码打开所有3个文件,并检查它们的文件状态,这是好习惯,因为程序可以在较早的时间就能检测到可能的错误,比如记录格式不匹配等。
第88行到第89行的代码初始读交易文件,并检查是否为空文件,如果为空文件,将HIGH-VALUES的值赋给交易账号。第92行到第97行的代码初始读旧主文件,如果读到文件尾,也是将HIGH-VALUES的值赋给旧主文件的账号栏位中,以标志文件的结束。如果读到有效的记录就执行NOT AT END短语后面的语句,将旧主文件的记录内容传送到新主文件记录工作区中,作为处理新主文件记录的基础。
第100行到第104行的代码确定活动键。活动键是交易文件和旧主文件记录键的较小者。所谓平衡线算法,你可以想象成交易文件和旧主文件从同一个起跑线开始跑步,它们比的不是谁更快而是谁比谁慢,换句话说,当旧主文件跑到前面(旧主文件的记录键大于交易文件的记录键)时,旧主文件就会停下来,等到交易文件赶上它(所有小于主文件记录键的交易记录处理完)。当两个文件的记录键一样时,就将交易文件的所有记录应用(修改)到对应的旧主文件记录中,并将交易更新的结果写到新主文件中,然后大家再往前跑一步。如果交易文件跑到前面(交易文件的记录键大于主文件的记录键),说明旧主文件中有些记录今天没有发生交易,交易文件就要停下来,直到所有掉到后面的旧主文件记录复制(写)到新主文件中为止。这时,交易文件和旧主文件又回到同一起跑线,再一起前进直到所有的交易记录和旧主文件记录处理完为止。
第107 行到第111 行的代码设置KEY-ALLOCATED-SWITCH的状态,只有当KEY-ALLOCATED-SWITCH设置成YES时,记录才写到新主文件中。换句话说,删除只是将开关设置为NO,而不写新主文件记录。
第113行到第114行的PERFORM…UNTIL语句将多笔交易记录应用到同一个主文件中,请注意,平衡线算法的一个前提条件是交易文件和旧主文件必须都是按照账号的顺序排列好的,这样,我们才可以将同一账号的交易记录放在一起处理。第121行到第135行的代码分别对合法的5种交易(开户、销户、修改账户资料、存款和取款)进行处理,处理方法简单明了,我们就不做详细的说明了。需要提醒的是,对于销户(CLS)交易,只是将KEY-ALLOCATED-SWITCH的状态改成了NO以确保旧主文件的记录在第138行的1080-WRITE-BKMASTN程序段中不会写到新主文件中,以达到销户的目的。如果交易不是合法的5种交易,第133行的代码就会显示错误信息。
第78行到第79行的PERFORM…UNTIL语句循环处理所用的交易文件和旧主文件,直到活动键的值为HIGH-VALUES,即所有的交易和主文件记录处理完为止。第81行到第85行的代码关闭所有的3个文件并停止程序的运行。
000001 IDENTIFICATION DIVISION. 000002 PROGRAM-ID. BKUPD1. 000003 AUTHOR. NEWMAN LV. 000004 000005 ENVIRONMENT DIVISION. 000006 CONFIGURATION SECTION. 000007 SOURCE-COMPUTER. IBM-ZSERIES. 000008 OBJECT-COMPUTER. IBM-ZSERIES. 000009 000010 INPUT-OUTPUT SECTION. 000011 FILE-CONTROL. 000012 SELECT BKTRAN-FILE ASSIGN TO UT-S-BKTRAN → 输入交易文件 000013 FILE STATUS IS WS-BKTRAN-STATUS 000014 . 000015 SELECT BKMASTO-FILE ASSIGN TO UT-S-BKMASTO → 输入旧主文件 000016 FILE STATUS IS WS-BKMASTO-STATUS 000017 . 000018 SELECT BKMASTN-FILE ASSIGN TO UT-S-BKMASTN → 输出新主文件 000019 FILE STATUS IS WS-BKMASTN-STATUS 000020 . 000021 DATA DIVISION. 000022 FILE SECTION. 000023 FD BKTRAN-FILE 000024 LABEL RECORDS ARE STANDARD 000025 RECORDING MODE IS F 000026 RECORD CONTAINS 80 CHARACTERS 000027 BLOCK CONTAINS 0 RECORDS 000028 DATA RECORD IS BKTRAN-RECORD. 000029 COPY BKTRAN REPLACING ==:BKTRAN:== BY ==BKTRAN==. 000030 000031 FD BKMASTO-FILE 000032 LABEL RECORDS ARE STANDARD 000033 RECORDING MODE IS F 000034 RECORD CONTAINS 100 CHARACTERS 000035 BLOCK CONTAINS 0 RECORDS 000036 DATA RECORD IS BKMASTO-RECORD. 000037 COPY BKMAST REPLACING ==:BKMAST:== BY ==BKMASTO==. 000038 000039 FD BKMASTN-FILE 000040 LABEL RECORDS ARE STANDARD 000041 RECORDING MODE IS F 000042 RECORD CONTAINS 100 CHARACTERS 000043 BLOCK CONTAINS 0 RECORDS 000044 DATA RECORD IS BKMASTN-RECORD. 000045 COPY BKMAST REPLACING ==:BKMAST:== BY ==BKMASTN==. 000046 000047 WORKING-STORAGE SECTION. 000048 01 FILLER PIC X(15) VALUE 'WS BEGINS HERE!'. 000049 COPY BKTRAN REPLACING ==:BKTRAN:== BY ==WS-BKTRAN==. 000050 COPY BKMAST REPLACING ==:BKMAST:== BY ==WS-BKMASTO==. 000051 COPY BKMAST REPLACING ==:BKMAST:== BY ==WS-BKMASTN==. 000052 01 WS-BALANCE-LINE-SWITCHES. 000053 05 WS-ACTIVE-KEY PIC X(14). 000054 05 WS-KEY-ALLOCATED-SWITCH PIC X(03). 000055 01 WS-FILE-STATUS. 000056 05 WS-BKTRAN-STATUS PIC X(02). 000057 05 WS-BKMASTO-STATUS PIC X(02). 000058 05 WS-BKMASTN-STATUS PIC X(02). 000059 000060 PROCEDURE DIVISION. 000061 1000-UPDATE-MASTER-FILE. 000062 OPEN INPUT BKTRAN-FILE 000063 BKMASTO-FILE 000064 OUTPUT BKMASTN-FILE 000065 IF WS-BKTRAN-STATUS NOT = '00' → 检查交易文件的状态 000066 DISPLAY 'BKTRAN FILE ERROR:' WS-BKTRAN-STATUS 000067 END-IF 000068 IF WS-BKMASTO-STATUS NOT = '00' → 检查旧主文件的状态 000069 DISPLAY 'BKMASTO FILE ERROR:' WS-BKMASTO-STATUS 000070 END-IF 000071 IF WS-BKMASTN-STATUS NOT = '00' → 检查新主文件的状态 000072 DISPLAY 'BKMASTN FILE ERROR:' WS-BKMASTN-STATUS 000073 END-IF 000074 . 000075 PERFORM 1020-READ-BKTRAN-FILE 000076 PERFORM 1030-READ-BKMASTO-FILE 000077 PERFORM 1040-CHOOSE-ACTIVE-KEY 000078 PERFORM 1050-PROCESS-ACTIVE-KEY 000079 UNTIL WS-ACTIVE-KEY = HIGH-VALUES 000080 . 000081 CLOSE BKTRAN-FILE 000082 BKMASTO-FILE 000083 BKMASTN-FILE 000084 . 000085 STOP RUN 000086 . 000087 1020-READ-BKTRAN-FILE. → 初始读交易文件 000088 READ BKTRAN-FILE INTO WS-BKTRAN-RECORD 000089 AT END MOVE HIGH-VALUES TO WS-BKTRAN-AC-NO. 000090 000091 1030-READ-BKMASTO-FILE. → 初始读旧主文件 000092 READ BKMASTO-FILE INTO WS-BKMASTO-RECORD 000093 AT END 000094 MOVE HIGH-VALUES TO WS-BKMASTO-AC-NO 000095 NOT AT END 000096 MOVE WS-BKMASTO-RECORD TO WS-BKMASTN-RECORD 000097 END-READ 000098 . 000099 1040-CHOOSE-ACTIVE-KEY. → 选择活动键 000100 IF WS-BKTRAN-AC-NO < WS-BKMASTO-AC-NO 000101 MOVE WS-BKTRAN-AC-NO TO WS-ACTIVE-KEY 000102 ELSE 000103 MOVE WS-BKMASTO-AC-NO TO WS-ACTIVE-KEY 000104 END-IF 000105 . 000106 1050-PROCESS-ACTIVE-KEY. 000107 IF WS-BKMASTO-AC-NO = WS-ACTIVE-KEY 000108 MOVE 'YES' TO WS-KEY-ALLOCATED-SWITCH 000109 ELSE 000110 MOVE 'NO' TO WS-KEY-ALLOCATED-SWITCH 000111 END-IF 000112 . 000113 PERFORM 1070-APPLY-TRANS-TO-MASTER → 多笔交易应用于单笔主文件记录 000114 UNTIL WS-ACTIVE-KEY NOT EQUAL WS-BKTRAN-AC-NO 000115 . 000116 PERFORM 1080-WRITE-BKMASTN → 写新主文件记录 000117 . 000118 PERFORM 1040-CHOOSE-ACTIVE-KEY → 选择下一个活动键 000119 . 000120 1070-APPLY-TRANS-TO-MASTER. 000121 EVALUATE WS-BKTRAN-TX-CODE 000122 WHEN 'OPN' → 检查所有合法的交易码 000123 PERFORM 1090-ADD-NEW-RECORD 000124 WHEN 'UPD' 000125 PERFORM 1100-UPDATE-OLD-RECORD 000126 WHEN 'CLS' 000127 PERFORM 1110-DELETE-OLD-RECORD 000128 WHEN 'DEP' 000129 PERFORM 1120-DEPOSIT-OLD-RECORD 000130 WHEN 'WIT' 000131 PERFORM 1130-WITHDRAW-OLD-RECORD 000132 WHEN OTHER → 非法交易码,报错! 000133 DISPLAY 'TX-CODE ERROR:' WS-BKTRAN-TX-CODE 000134 END-EVALUATE 000135 . 000136 PERFORM 1020-READ-BKTRAN-FILE → 读下一笔交易文件 000137 . 000138 1080-WRITE-BKMASTN. → 只有ALLOCATED标志为YES的才删除 000139 IF WS-KEY-ALLOCATED-SWITCH = 'YES' 对于销户(CLS)交易,标志为NO 000140 WRITE BKMASTN-RECORD FROM WS-BKMASTN-RECORD 000141 IF WS-BKMASTN-STATUS NOT = '00' 000142 DISPLAY 'ERROR ON WRITE BKMASTN:' WS-BKMASTN-STATUS 000143 . 000144 PERFORM 1030-READ-BKMASTO-FILE → 读下一笔旧主文件 000145 . 000146 1090-ADD-NEW-RECORD. → 新开户,直接生成新记录 000147 DISPLAY '1090-ADD-NEW-RECORD EnterED:' WS-BKTRAN-AC-NO 000148 IF WS-KEY-ALLOCATED-SWITCH = ‘YES' 000149 DISPLAY 'ERROR,DUPLICATE OPEN AC:' WS-BKTRAN-AC-NO 000150 ELSE 000151 MOVE 'YES' TO WS-KEY-ALLOCATED-SWITCH 000152 INITIALIZE WS-BKMASTN-RECORD 000153 MOVE WS-BKTRAN-AC-NO TO WS-BKMASTN-AC-NO 000154 MOVE WS-BKTRAN-LNAME TO WS-BKMASTN-LNAME 000155 MOVE WS-BKTRAN-FNAME TO WS-BKMASTN-FNAME 000156 MOVE WS-BKTRAN-ID TO WS-BKMASTN-ID 000157 MOVE WS-BKTRAN-ADDR TO WS-BKMASTN-ADDR 000158 MOVE ZEROS TO WS-BKMASTN-VALUE-DATE 000159 WS-BKMASTN-TRAN-DATE 000160 WS-BKMASTN-BAL 000161 END-IF 000162 . 000163 1100-UPDATE-OLD-RECORD. → 修改交易,修改旧主文件记录 000164 DISPLAY '1100-UPDATE-OLD RECORD EnterED' WS-BKTRAN-AC-NO 000165 IF WS-KEY-ALLOCATED-SWITCH = 'YES' 000166 IF WS-BKTRAN-LNAME NOT = SPACES 000167 MOVE WS-BKTRAN-LNAME TO WS-BKMASTN-LNAME 000168 END-IF 000169 IF WS-BKTRAN-FNAME NOT = SPACES 000170 MOVE WS-BKTRAN-FNAME TO WS-BKMASTN-FNAME 000171 END-IF 000172 IF WS-BKTRAN-ID NOT = SPACES 000173 MOVE WS-BKTRAN-ID TO WS-BKMASTN-ID 000174 END-IF 000175 IF WS-BKTRAN-ADDR NOT = SPACES 000176 MOVE WS-BKTRAN-ADDR TO WS-BKMASTN-ADDR 000177 END-IF 000178 ELSE 000179 DISPLAY ‘ERROR,NO MATCHING RECORD:' WS-BKTRAN-AC-NO 000180 END-IF 000181 . 000182 1110-DELETE-OLD-RECORD. → 删除交易,置ALLOCATED标志为NO 000183 IF WS-KEY-ALLOCATED-SWITCH = 'YES' 000184 MOVE 'NO' TO WS-KEY-ALLOCATED-SWITCH 000185 ELSE 000186 DISPLAY 'ERROR-NO MATCHING RECORD:' WS-BKTRAN-AC-NO 000187 END-IF 000188 . 000189 1120-DEPOSIT-OLD-RECORD.→ 存款交易,余额增加 000190 DISPLAY '1120-DEPOSIT-OLD RECORD EnterED' WS-BKTRAN-AC-NO 000191 IF WS-KEY-ALLOCATED-SWITCH = 'YES' 000192 COMPUTE WS-BKMASTN-BAL = 000193 WS-BKTRAN-TX-AMT + WS-BKMASTN-BAL 000194 MOVE WS-BKTRAN-TRAN-DATE TO WS-BKMASTN-TRAN-DATE 000195 IF WS-BKMASTN-VALUE-DATE = ZEROS 000196 MOVE WS-BKTRAN-TRAN-DATE TO WS-BKMASTN-VALUE-DATE 000197 END-IF 000198 ELSE 000199 DISPLAY 'ERROR,NO MATCHING RECORD:' WS-BKTRAN-AC-NO 000200 END-IF 000201 . 000202 1130-WITHDRAW-OLD-RECORD.→ 取款交易,余额减少 000203 DISPLAY '1130-WITHDWAW-OLD RECORD EnterED' WS-BKTRAN-AC-NO 000204 IF WS-KEY-ALLOCATED-SWITCH = 'YES' 000205 COMPUTE WS-BKMASTN-BAL = 000206 WS-BKMASTN-BAL - WS-BKTRAN-TX-AMT 000207 MOVE WS-BKTRAN-TRAN-DATE TO WS-BKMASTN-TRAN-DATE 000208 IF WS-BKMASTN-VALUE-DATE = ZEROS 000209 MOVE WS-BKTRAN-TRAN-DATE TO WS-BKMASTN-VALUE-DATE 000210 END-IF 000211 ELSE 000212 DISPLAY 'ERROR,NO MATCHING RECORD:' WS-BKTRAN-AC-NO 000213 END-IF 000214 .