Удаление / Пропуск нескольких записей с помощью Easytrieve/Cobol
Предположим, у меня есть файл A с данными ниже:
A1.01
A2.02
A4.03
A6.01
И файл B, имеющий следующие данные:
A2.02 xyshahaslsl
A2.02 dkjhsldhsds
A2.02 ewewhrewjws
A4.03 wejwejwrewl
A4.03 wejedededee
A5.01 kdkgskhdgss
A5.02 fljsdfjdfjd
A5.03 sdjdhsdhsld
A7.04 jhsdhskdhsd
A7.07 dsjdhslkhds
Требуется удалить записи, присутствующие в файле A, из файла B, если они совпадают с данными первых двух букв записей второго файла.
Поэтому вывод должен выглядеть так:
A5.01 kdkgskhdgss
A5.02 fljsdfjdfjd
A5.03 sdjdhsdhsld
A7.04 jhsdhskdhsd
A7.07 dsjdhslkhds
У меня есть файл A, содержащий 400 записей, и файл B, содержащий полмиллиона записей. Я запустил программу COBOL, но она работала слишком долго.
Программная логика Cobol выглядит следующим образом:
Здесь я взял полмиллиона записей, контурирующих файл, как А.
И файл, содержащий 400 записей в виде файла B.
WORKING-STORAGE SECTION.
01 WS-RECORDS-WRITTEN PIC 9(8) VALUE ZEROES.
01 WS-RECORDS-DELETED PIC 9(8) VALUE ZEROES.
01 WS-INSERT-FILE-STATUS PIC X(2).
01 WS-EOFA PIC A(1) VALUE 'N'.
01 WS-EOFB PIC A(1) VALUE 'N'.
01 WS-FLAG-FOUND PIC A(1) VALUE 'N'.
PROCEDURE DIVISION.
MAIN-PARA.
OPEN INPUT IFILEA
OPEN OUTPUT OFILE
PERFORM PARA0 THRU PARA0-EXIT UNTIL WS-EOFA = "Y"
CLOSE IFILEA
CLOSE OFILE
STOP RUN.
EXIT.
PARA0.
READ IFILEA
AT END MOVE "Y" TO WS-EOFA
END-READ
IF WS-EOFA = "N"
OPEN INPUT IFILEB
MOVE "N" TO WS-EOFB
MOVE "N" TO WS-FLAG-FOUND
PERFORM PARA1 THRU PARA1-EXIT UNTIL WS-EOFB = "Y"
OR WS-FLAG-FOUND = "Y"
IF WS-FLAG-FOUND = "N"
WRITE F2RECORD FROM F0RECORD
END-IF
CLOSE IFILEB
END-IF.
PARA0-EXIT.
EXIT.
PARA1.
READ IFILEB
AT END MOVE "Y" TO WS-EOFB
END-READ
IF OSS024S-TRACKING-ID = OSS024V-REC
* SKIP THE RECORD
MOVE "Y" TO WS-FLAG-FOUND
END-IF.
PARA1-EXIT.
EXIT.
1 ответ
[Образец File-control, файловый раздел и необходимое рабочее хранилище добавлены для ясности.
Следуйте за прыгающим мячом для других файлов. Названия файлов, на которые ссылаются, предназначены для моего тестирования. образец только для краткости]
FILE-CONTROL.
SELECT FILE-A ASSIGN TO "Q30309414.EXC"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FILE-A-STATUS.
FILE SECTION.
FD FILE-A.
01 FILE-A-REC.
05 FILE-A-FIELD PIC X(02).
05 FILLER PIC X(18).
WORKING-STORAGE SECTION.
01 FILE-A-STATUS PIC X(02).
88 EOF-A VALUE '10'.
MAINLINE.
OPEN INPUT FILE-A.
OPEN INPUT FILE-B.
OPEN OUTPUT FILE-O.
MOVE LOW-VALUES TO FILE-A-REC.
PERFORM READ-AND-FILTER
UNTIL EOF-B.
CLOSE FILE-A.
CLOSE FILE-B.
CLOSE FILE-O.
STOP RUN.
READ-AND-FILTER.
READ FILE-B AT END MOVE HIGH-VALUES TO FILE-B-REC.
PERFORM READ-NEXT-FILTER
UNTIL FILE-B-FIELD IS NOT GREATER THAN FILE-A-FIELD.
IF FILE-B-FIELD IS LESS THAN FILE-A-FIELD
WRITE FILE-O-REC FROM FILE-B-REC.
READ-NEXT-FILTER.
IF FILE-B-FIELD IS GREATER THAN FILE-A-FIELD
READ FILE-A
AT END MOVE HIGH-VALUES TO FILE-A-REC.
Нет необходимости в каких-либо флагах, только статусы файлов. Конечно, нет необходимости в злых действиях, которые создают код, зависящий от макета.
Это предполагает, что ваши данные отсортированы, как вы указали. В противном случае подход был бы другим - считайте соответствующее поле файла исключений (два символа) в таблицу рабочего хранилища, сортируйте и ищите в таблице совпадение с каждой прочитанной записью основного файла.