IBM主机技术一本通
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

8.2 平衡线算法

每个程序员都会碰到顺序修改的问题,实际上,很多国外有关COBOL的图书已经讨论了这一主题。但是,很少的程序员或作者,如果有的话,编制了实际上通用的带有简短解释的完整程序。

平衡线算法至少需要3个文件:一个旧主文件、一个新主文件和一个或多个交易文件。假定交易文件和旧主文件是按相同的关键字顺序排列的。在旧主文件中,对于每个记录,关键字的值必须是唯一的,但对交易文件则可以是不唯一的;亦即,可以有几笔交易对应于同一主文件记录。

我们在本书中将平衡线算法使用到银行主文件的更新中,我们允许有5种类型的交易:即开户(增加)、销户(删除)、修改、存款和取款。一笔给定的交易只影响单个主文件记录,如前所述,对于相同的主文件记录可以有多笔交易,也可能有多个交易文件。交易文件和主文件都是以账号为关键字的,同一个账号在主文件中只有一条记录,但同一个账号在交易文件中可以出现多次,因为用户可能每天发生多笔存款或取款交易。

活动键的概念是这一算法的基础。活动键是旧主文件和当前正在处理的交易键的较小者。因此,如果交易键小于旧主文件链,活动键就等于交易键;如果交易链和旧主文件键相等,活动键就等于其中任意一个;最后,如果旧主文件键小于交易键,则活动键就设为旧主文件的。注意,这一技术很容易推广到多个交易文件的情形,活动键总是定义为当前处理的所有键的最小值。

下面程序包含整个主文件更新处理的伪代码,为简单起见,只有单个交易文件。开始时,从每个文件中读第1个记录,并决定第1个活动键。只有关键字等于活动键的记录才允许去参加主文件更新处理。最后,每个文件的关键字将等于HIGH-VALUES并且算法结束。

        OPEN FILES
        READ TRANSACTION-FILE
            AT END MOVE HIGH-VALUES TO TRANSACTION-KEY
        READ OLD-MASTER-FILE
            AT END MOVE HIGH-VALUES TO OLD-MASTER-KEY
        CHOOSE FIRST ACTIVE-KEY
        DO WHILE ACTIVE-KEY NOT= HIGH-VALUES
            IF OLD-MASTER-KEY=ACTIVE-KEY
                MOVE OLD-MASTER-RECORD TO NEW-MASTER-RECORD
                READ OLD-MASTER-FILE
        AT END MOVE HIGH-VALUES TO OLD-MASTER-KEY
            ENDIF
            DO WHILE TRANSACTION-KEY=ACTIVE-KEY
                APPLY TRANSACTION TO NEW-MASTER-RECORD
                READ TRANSACTION-FILE
        AT END MOVE HIGH-VALUES TO TRANSACTION-KEY
            ENDDO
            IF NO DELETION WAS PROCESSED
                WRITE NEW-MASTER-RECORD
            ENDIF
        CHOOSE NEXT ACTIVE-KEY
        ENDDO
        CLOSE FILES
        STOP RUN

上面的主循环重复执行,直到活动键等于HIGH-VALUES;亦即,直到旧主文件和交易文件没有数据为止。如果当前旧主文件记录的关键字等于活动键,则旧主文件记录被传送到新主文件中,并从旧主文件中读出另一记录。第2个循环将所有等于活动键的交易应用到当前主文件记录中。每个交易处理完后,在这一内部循环中,重复读交易文件记录。当交易关键字不再等于活动键时,就检查是否要处理删除,如果没有,就写新主文件记录。选择下一个活动键,继续外面的循环。

下面的程序扩充了上面的逻辑以包括错误处理。尽管你可以假定交易文件本身是合法的,但在实际处理中仍会有别的错误情形出现,特别地,修改程序必须拒绝企图增加旧主文件已经存在的记录的交易(即重复的增加),也应当拒绝企图修改或删除不存在记录的交易(即错误地复制的交易键)。

完成这一错误处理的最容易的方法是通过给活动键的每一个值指定一分配状态,亦即,关键字的值要么已分配,要么没有分配。删除现存记录,将使状态从ON变成OFF;增加新记录将状态从OFF变成ON。企图增加一个状态已经为ON的键,表示是重复增加。按类似的方法,企图修改或删除分配状态为OFF的记录也隐含一种错误,因为交易键在旧主文件中不存在。

只有当KEY-ALLOCATED-SWITCH设置成YES时,记录才写到新主文件中。换句话说,删除只是将开关设置为NO,而不写记录。下面的伪代码除包含有KEY-ALLOCATED-SWITCH外,其他的与前面的讨论一样。

        OPEN FILES
        READ TRANSACTION-FILE
          AT END MOVE HIGH-VALUES TO TRANSACTION-KEY
        READ OLD-MASTER-FILE
          AT END MOVE HIGH-VALUES TO OLD-MASTER-KEY
        CHOOSE FIRST ACTIVE-KEY
        DO WHILE ACTIVE-KEY NOT = HIGH-VALUES
            IF OLD-MASTER-KEY= ACTIVE-KEY
                MOVE ‘YES’TO KEY-ALLOCATED-SWITCH
                MOVE OLD-MASTER-RECORD TO NEW-MASTER-RECORD
                READ OLD-MASTER-FILE
                  AT END MOVE HIGH-VALUES TO OLD-MASTER-KEY
            ELSE(ACTIVE-KEY IS NOT IN OLD-MASTER-FILE)
              MOVE ‘NO’TO KEY-ALLOCATED-SWITCH
        ENDIF
        DO WHILE TRANSACTION-KEY= ACTIVE-KEY
              EVALUATE TRANSACTION-CODE
                  WHEN OPEN(开户)
                      IF KEY-ALLOCATED-SWITCH= ‘YES’
                            WRITE ‘ERROR-Duplicate record’
                      ELSE(ACTIVE-KEY IS NOT IN OLD-MASTER-FILE)
                            MOVE TRANSACTION-RECORD TO NEW-MASTER-RECORD
                            MOVE ‘YES’TO KEY-ALLOCATED-SWITCH
                      ENDIF
                  WHEN UPDATE(修改客户资料)
                      IF KEY-ALLOCATED-SWITCH= ‘YES’
                            PROCESS UPDATE
                      ELSE(ACTIVE-KEY IS NOT IN OLD-MASTER-FILE)
                            WRITE ‘ERROR-Record not Found’
                      ENDIF
                WHEN CLOSE(销户)
                      IF KEY-ALLOCATED-SWITCH= ‘YES’
                            MOVE ‘NO’TO KEY-ALLOCATED-SWITCH
                            PROCESS DELETION
                      ELSE(ACTIVE-KEY IS NOT IN OLD-MASTER-FILE)
                            WRITE ‘ERROR-Record not MATCH’
                      ENDIF
                WHEN DEPOSIT(存款)
                      IF KEY-ALLOCATED-SWITCH= ‘YES’
                            MOVE ‘NO’TO KEY-ALLOCATED-SWITCH
                            PROCESS DEPOSIT
                      ELSE(ACTIVE-KEY IS NOT IN OLD-MASTER-FILE)
                            WRITE ‘ERROR-Not Exist’
                      ENDIF
                WHEN WITHDRAW(取款)
                      IF KEY-ALLOCATED-SWITCH= ‘YES’
                            MOVE ‘NO’TO KEY-ALLOCATED-SWITCH
                            PROCESS WITHDRAW
                      ELSE(ACTIVE-KEY IS NOT IN OLD-MASTER-FILE)
                            WRITE ‘ERROR-Not Exist’
                      ENDIF
                WHEN OTHER
                      WRITE ‘ERROR-INVALID TRANSACTION CODE’
            END-EVALUATE
            READ TRANSACTION-FILE
                AT END MOVE HIGH-VALUES TO TRANSACTION-KEY
            ENDDO
            IF KEY-ALLOCATED-SWITCH= ‘YES’
                WRITE NEW-MASTER-RECORD
            ENDIF
            CHOOSE NEXT ACTIVE-KEY
        ENDDO
        CLOSE FILES
        STOP RUN

读者应当相信上面代码的通用性,进一步说,对应于同一关键字的多个交易,可以按任意顺序出现。例如,如果交易是以增加和更正的顺序输入,记录将按相同的顺序增加和更正。但是,如果在增加的前面更正,则更正会标志为不匹配,而且只有增加发生作用。对于同一键的二次增加将导致第1次增加成功,第2次则标记为出错——重复增加。对于同一账户,交易可以按开户、修改、存款、取款和销户的顺序处理,但是,其他的组合顺序将产生错误信息,说明企图修改或删除旧主文件中不存在的记录。换句话说,对应于同一关键字的多笔交易可以按任意顺序出现,不要求对交易代码做第2次分类。