feat: add benchmark-programs — 58 telecom COBOL test programs

作为子目录纳入系统,与核心测试管道协同

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
NB-076
2026-06-25 09:53:21 +08:00
parent 50f9f0f52f
commit 94400d50d4
278 changed files with 44125 additions and 0 deletions
@@ -0,0 +1 @@
00000
@@ -0,0 +1 @@
00000000000000000
+30
View File
@@ -0,0 +1,30 @@
# 34-sort — SORT Processing Program
## 电信业务场景
CDR排序。使用SORT语句对CDR明细进行排序(按主叫号码升序/降序、通话时长多键排序),支持INPUT/OUTPUT PROCEDURE。
## Purpose
Comprehensive demonstration of COBOL SORT statement capabilities, covering SR-N001 through SR-N010.
## Test Coverage
| ID | Test | Description |
|----|------|-------------|
| SR-N001 | Ascending SORT | USING INPUT-FILE / GIVING OUTPUT-FILE, ASCENDING KEY |
| SR-N002 | Descending SORT | DESCENDING KEY sort |
| SR-N003 | Multi-key SORT | ASCENDING KEY + DESCENDING KEY (mixed) |
| SR-N004 | INPUT PROCEDURE | FILTER-INPUT section, only records with VALUE > 200 |
| SR-N005 | OUTPUT PROCEDURE | SUMMARIZE-OUTPUT with key break totals |
| SR-N006 | 0-record SORT | Empty input file |
| SR-N007 | 1-record SORT | Single record input |
| SR-N008 | INPUT/OUTPUT PROCEDURE | Both procedures combined with editing |
| SR-N009 | Duplicate key SORT | Three records with same key (stability check) |
| SR-N010 | Descending multi-key | DESCENDING + ASCENDING combined |
## Key Techniques
- SORT USING/GIVING
- INPUT PROCEDURE / OUTPUT PROCEDURE
- ASCENDING KEY / DESCENDING KEY
- RELEASE statement (input procedure)
- RETURN statement (output procedure)
- Key break processing in output procedure
+1
View File
@@ -0,0 +1 @@
00000
@@ -0,0 +1 @@
00000000000000000
+1444
View File
@@ -0,0 +1,1444 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. Main34Sort.
*> ============================================================
*> 34-sort : CDR排序 (CDR Sorting before Billing)
*> Input : sort-input.dat (未排序CDR明细)
*> Output: sort-output.dat (按客户/时间排序CDR)
*> Summary: sort-summary.txt (排序结果汇总)
*> Stats : sort-stats.txt (排序统计)
*> Audit : sort-audit.txt (审计跟踪)
*> Report : sort-report.txt (多层断点汇总报告)
*> Coverage: SR-N001~N015
*> ============================================================
*> CDR SORT processing program for telecom billing
*> Tests: USING/GIVING, INPUT/OUTPUT PROCEDURE,
*> multi-key sort, stable sort, 0/1 record sort,
*> enhanced validation, multi-level keybreak,
*> audit trail, hash totals, FILE STATUS checks
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE ASSIGN TO "sort-input.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-INPUT.
SELECT OUTPUT-FILE ASSIGN TO "sort-output.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-OUTPUT.
SELECT WORK-FILE ASSIGN TO "sort-work.tmp"
FILE STATUS IS FS-WORK.
SELECT SUMMARY-FILE ASSIGN TO "sort-summary.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-SUMMARY.
SELECT SORT-STATS-FILE ASSIGN TO "sort-stats.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-STATS.
SELECT AUDIT-FILE ASSIGN TO "sort-audit.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-AUDIT.
SELECT REPORT-FILE ASSIGN TO "sort-report.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-REPORT.
SELECT WORK-FILE2 ASSIGN TO "sort-work2.tmp"
FILE STATUS IS FS-WORK2.
DATA DIVISION.
FILE SECTION.
FD INPUT-FILE.
01 INPUT-REC.
05 IN-KEY PIC X(10).
05 IN-DATA PIC X(20).
05 IN-VALUE PIC 9(05).
FD OUTPUT-FILE.
01 OUTPUT-REC.
05 OUT-KEY PIC X(10).
05 OUT-DATA PIC X(20).
05 OUT-VALUE PIC 9(05).
SD WORK-FILE.
01 WORK-REC.
05 WR-KEY PIC X(10).
05 WR-DATA PIC X(20).
05 WR-VALUE PIC 9(05).
SD WORK-FILE2.
01 WORK2-REC.
05 W2R-KEY PIC X(10).
05 W2R-CUSTOMER PIC X(11).
05 W2R-PLAN PIC X(05).
05 W2R-CALL-TYPE PIC X(02).
05 W2R-DATE PIC 9(08).
05 W2R-DURATION PIC 9(09).
FD SUMMARY-FILE.
01 SUMMARY-REC PIC X(80).
FD SORT-STATS-FILE.
01 STATS-REC PIC X(80).
FD AUDIT-FILE.
01 AUDIT-REC PIC X(80).
FD REPORT-FILE.
01 REPORT-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-CDR-REF.
COPY "telecom/TEL-CDR.cpy".
*> FILE STATUS fields
01 FS-INPUT PIC X(02).
88 FS-INPUT-OK VALUE "00".
88 FS-INPUT-EOF VALUE "10".
01 FS-OUTPUT PIC X(02).
88 FS-OUTPUT-OK VALUE "00".
01 FS-WORK PIC X(02).
01 FS-SUMMARY PIC X(02).
88 FS-SUMMARY-OK VALUE "00".
01 FS-STATS PIC X(02).
88 FS-STATS-OK VALUE "00".
01 FS-AUDIT PIC X(02).
88 FS-AUDIT-OK VALUE "00".
01 FS-REPORT PIC X(02).
88 FS-REPORT-OK VALUE "00".
01 FS-WORK2 PIC X(02).
*> Original WS fields (preserved for existing tests)
01 WS-EOF PIC X(01) VALUE "N".
88 WS-EOF-Y VALUE "Y".
01 WS-RECORD-COUNT PIC 9(02) VALUE 0.
01 WS-TOTAL-VALUE PIC 9(07) VALUE 0.
01 WS-GROUP-COUNT PIC 9(02) VALUE 0.
01 WS-GROUP-VALUE PIC 9(07) VALUE 0.
01 WS-PREV-KEY PIC X(10).
01 WS-HEADER-LINE.
05 FILLER PIC X(10) VALUE "KEY ".
05 FILLER PIC X(22) VALUE "DATA ".
05 FILLER PIC X(10) VALUE "VALUE ".
01 WS-DETAIL-LINE.
05 DL-KEY PIC X(10).
05 FILLER PIC X(02) VALUE SPACES.
05 DL-DATA PIC X(20).
05 FILLER PIC X(02) VALUE SPACES.
05 DL-VALUE PIC Z(9)9.
01 WS-SUMMARY-LINE.
05 FILLER PIC X(20) VALUE "Group key: ".
05 SL-KEY PIC X(10).
05 FILLER PIC X(10) VALUE " Count: ".
05 SL-COUNT PIC Z(9).
05 FILLER PIC X(10) VALUE " Total: ".
05 SL-TOTAL PIC Z(9)9.
*> CDR test data (phone numbers + call durations)
01 TEST-DATA-AREA.
05 TEST-DATA OCCURS 9 TIMES.
10 TD-KEY PIC X(10).
10 TD-DATA PIC X(20).
10 TD-VALUE PIC 9(05).
01 TEST-DATA-VALUES.
05 FILLER PIC X(35) VALUE
"CDRB00000113800138001 00100".
05 FILLER PIC X(35) VALUE
"CDRA00000113900139001 00500".
05 FILLER PIC X(35) VALUE
"CDRC00000113700137001 00200".
05 FILLER PIC X(35) VALUE
"CDRA00000213600136001 00300".
05 FILLER PIC X(35) VALUE
"CDRB00000213500135001 00400".
05 FILLER PIC X(35) VALUE
"CDRA00000313400134001 00150".
05 FILLER PIC X(35) VALUE
"CDRC00000213300133001 00250".
05 FILLER PIC X(35) VALUE
"CDRB00000313200132001 00350".
05 FILLER PIC X(35) VALUE
"CDRA00000413100131001 00200".
01 TEST-DATA-REDEF REDEFINES TEST-DATA-VALUES.
05 TEST-DATA-ENTRY OCCURS 9 TIMES.
10 TDE-KEY PIC X(10).
10 TDE-DATA PIC X(20).
10 TDE-VALUE PIC 9(05).
01 IDX PIC 9(02).
*> ============================================================
*> New WS fields for enhanced telecom billing processing
*> ============================================================
*> Current timestamp from FUNCTION CURRENT-DATE (21 chars)
01 WS-CURRENT-DATE-TIME.
05 WS-CDT-DATE PIC 9(08).
05 WS-CDT-TIME PIC 9(06).
05 WS-CDT-MS PIC 9(02).
05 WS-CDT-OFFSET PIC 9(04).
05 WS-CDT-SIGN PIC X(01).
*> Batch control totals
01 WS-BATCH-CTL.
05 WS-BCT-INPUT-COUNT PIC 9(09) VALUE 0.
05 WS-BCT-SORTED-COUNT PIC 9(09) VALUE 0.
05 WS-BCT-FILTERED-COUNT PIC 9(09) VALUE 0.
05 WS-BCT-DUP-COUNT PIC 9(09) VALUE 0.
05 WS-BCT-INVALID-COUNT PIC 9(09) VALUE 0.
05 WS-BCT-HASH-TOTAL PIC 9(15) VALUE 0.
*> Sort statistics
01 WS-SORT-STATS.
05 WS-SS-INPUT-COUNT PIC 9(09) VALUE 0.
05 WS-SS-OUTPUT-COUNT PIC 9(09) VALUE 0.
05 WS-SS-FILTERED PIC 9(09) VALUE 0.
05 WS-SS-DUPLICATE-COUNT PIC 9(09) VALUE 0.
05 WS-SS-TOTAL-DURATION PIC 9(15) VALUE 0.
*> Audit message buffer
01 WS-AUDIT-MESSAGE PIC X(55).
*> Audit entry
01 WS-AUDIT-LINE.
05 FILLER PIC X(01) VALUE SPACE.
05 WS-AL-DATE PIC 9(08).
05 FILLER PIC X(01) VALUE SPACE.
05 WS-AL-TIME PIC 9(06).
05 FILLER PIC X(01) VALUE SPACE.
05 WS-AL-SEVERITY PIC X(01).
05 FILLER PIC X(02) VALUE SPACE.
05 WS-AL-MESSAGE PIC X(55).
01 WS-ERROR-SEVERITY PIC X(01).
88 WS-ERR-INFO VALUE "I".
88 WS-ERR-WARN VALUE "W".
88 WS-ERR-ERROR VALUE "E".
88 WS-ERR-FATAL VALUE "F".
*> Multi-level keybreak fields
01 WS-BREAK-CUSTOMER.
05 WS-BR-CUSTOMER PIC X(11).
05 WS-BR-CUST-COUNT PIC 9(09) VALUE 0.
05 WS-BR-CUST-DUR PIC 9(09) VALUE 0.
01 WS-BREAK-PLAN.
05 WS-BR-PLAN PIC X(05).
05 WS-BR-PLAN-COUNT PIC 9(09) VALUE 0.
05 WS-BR-PLAN-DUR PIC 9(09) VALUE 0.
01 WS-BREAK-CALL-TYPE.
05 WS-BR-CALL-TYPE PIC X(02).
05 WS-BR-CT-COUNT PIC 9(09) VALUE 0.
05 WS-BR-CT-DUR PIC 9(09) VALUE 0.
01 WS-PREV-W2R-KEY PIC X(10).
01 WS-PREV-CUSTOMER PIC X(11).
01 WS-PREV-PLAN PIC X(05).
01 WS-PREV-CALLTYPE PIC X(02).
01 WS-PREV-DATE PIC 9(08).
*> Enriched CDR field buffers
01 WS-ECDR-ID PIC X(10).
01 WS-ECDR-CUSTOMER PIC X(11).
01 WS-ECDR-PLAN PIC X(05).
01 WS-ECDR-CALL-TYPE PIC X(02).
01 WS-ECDR-DATE PIC 9(08).
01 WS-ECDR-DURATION PIC 9(09).
*> Enriched detail line for display
01 WS-ENH-DETAIL-LINE.
05 FILLER PIC X(02) VALUE SPACE.
05 EDL-ID PIC X(10).
05 FILLER PIC X(01) VALUE SPACE.
05 EDL-CUSTOMER PIC X(11).
05 FILLER PIC X(01) VALUE SPACE.
05 EDL-PLAN PIC X(05).
05 FILLER PIC X(01) VALUE SPACE.
05 EDL-CALL-TYPE PIC X(02).
05 FILLER PIC X(01) VALUE SPACE.
05 EDL-DATE PIC 9(08).
05 FILLER PIC X(01) VALUE SPACE.
05 EDL-DURATION PIC Z(9)9.
*> Report line templates
01 WS-RPT-HEADER1.
05 FILLER PIC X(30) VALUE
"TELECOM SORT REPORT - RUN AT ".
05 RPT1-DATE PIC 9(08).
05 FILLER PIC X(01) VALUE SPACE.
05 RPT1-TIME PIC 9(06).
01 WS-RPT-HEADER2.
05 FILLER PIC X(80) VALUE ALL "=".
01 WS-RPT-KEYBREAK-CUST.
05 FILLER PIC X(05) VALUE SPACES.
05 FILLER PIC X(18) VALUE "CUSTOMER: ".
05 RPT-CUST-ID PIC X(11).
05 FILLER PIC X(05) VALUE SPACES.
05 FILLER PIC X(08) VALUE "COUNT: ".
05 RPT-CUST-COUNT PIC Z(9)9.
05 FILLER PIC X(05) VALUE SPACES.
05 FILLER PIC X(10) VALUE "DURATION: ".
05 RPT-CUST-DUR PIC Z(9)9.
01 WS-RPT-KEYBREAK-PLAN.
05 FILLER PIC X(08) VALUE SPACES.
05 FILLER PIC X(15) VALUE " PLAN: ".
05 RPT-PLAN-ID PIC X(05).
05 FILLER PIC X(05) VALUE SPACES.
05 FILLER PIC X(08) VALUE "COUNT: ".
05 RPT-PLAN-COUNT PIC Z(9)9.
05 FILLER PIC X(05) VALUE SPACES.
05 FILLER PIC X(10) VALUE "DURATION: ".
05 RPT-PLAN-DUR PIC Z(9)9.
01 WS-RPT-KEYBREAK-CT.
05 FILLER PIC X(12) VALUE SPACES.
05 FILLER PIC X(13) VALUE "CALL TYPE: ".
05 RPT-CALL-TYPE PIC X(02).
05 FILLER PIC X(03) VALUE SPACES.
05 RPT-CALL-TYPE-NAME PIC X(15).
05 FILLER PIC X(05) VALUE SPACES.
05 FILLER PIC X(08) VALUE "COUNT: ".
05 RPT-CT-COUNT PIC Z(9)9.
05 FILLER PIC X(05) VALUE SPACES.
05 FILLER PIC X(10) VALUE "DURATION: ".
05 RPT-CT-DUR PIC Z(9)9.
01 WS-RPT-GRAND-TOTAL.
05 FILLER PIC X(25) VALUE
"GRAND TOTAL RECORDS: ".
05 RPT-GRAND-COUNT PIC Z(9)9.
05 FILLER PIC X(10) VALUE SPACES.
05 FILLER PIC X(15) VALUE "TOTAL DURATION: ".
05 RPT-GRAND-DUR PIC Z(9)9.
*> Enhanced CDR test data (telecom format)
*> Layout: 10-id + 11-customer + 11-callee + 5-plan + 2-type + 8-date + 9-dur = 56
*> We align to WORK2-REC fields: key(10)+cust(11)+plan(5)+type(2)+date(8)+dur(9) = 45
*> Store as concatenated 45-char strings
01 ENH-TEST-VALUES.
05 FILLER PIC X(45) VALUE
"CDR1000001186139000138001PSTDMO20260601000060000".
05 FILLER PIC X(45) VALUE
"CDR1000002186139000138001PSTDMO20260601000120000".
05 FILLER PIC X(45) VALUE
"CDR1000003186139000138001PRMMO20260602000300000".
05 FILLER PIC X(45) VALUE
"CDR1000004186138000139001PRMMO20260601000050000".
05 FILLER PIC X(45) VALUE
"CDR1000005186138000139001ECOMO20260601000100000".
05 FILLER PIC X(45) VALUE
"CDR1000006186138000139001PSTDMO20260603000350000".
05 FILLER PIC X(45) VALUE
"CDR1000007186140000138001PSTDMO20260601000450000".
05 FILLER PIC X(45) VALUE
"CDR1000008186139000139001PRMMO20260603000200000".
05 FILLER PIC X(45) VALUE
"CDR2000001186141000138001ECOMO20260601001500000".
05 FILLER PIC X(45) VALUE
"CDR2000002186141000138001ECOMO20260602002500000".
01 ENH-TEST-REDEF REDEFINES ENH-TEST-VALUES.
05 ENH-TEST-ENTRY OCCURS 10 TIMES.
10 ETE-ID PIC X(10).
10 ETE-CUSTOMER PIC X(11).
10 ETE-PLAN PIC X(05).
10 ETE-CALL-TYPE PIC X(02).
10 ETE-DATE PIC 9(08).
10 ETE-DURATION PIC 9(09).
01 ENH-IDX PIC 9(02).
*> Hash total work fields
01 WS-HASH-TOTAL PIC 9(15) VALUE 0.
01 WS-DURATION-HASH PIC 9(15) VALUE 0.
01 WS-DURATION-CHECK PIC 9(15) VALUE 0.
*> Duplicate test data
01 DUP-VALUES.
05 FILLER PIC X(45) VALUE
"CDR-DUP00113800138001PSTDMO20260601000100000".
05 FILLER PIC X(45) VALUE
"CDR-DUP00213800138001PSTDMO20260602000200000".
05 FILLER PIC X(45) VALUE
"CDR-DUP00313800138001PSTDMO20260601000100000".
05 FILLER PIC X(45) VALUE
"CDR-DUP00413900139001PRMMT20260601000300000".
05 FILLER PIC X(45) VALUE
"CDR-DUP00513900139001PRMMT20260601000300000".
01 DUP-REDEF REDEFINES DUP-VALUES.
05 DUP-ENTRY OCCURS 5 TIMES.
10 DE-ID PIC X(10).
10 DE-CUSTOMER PIC X(11).
10 DE-PLAN PIC X(05).
10 DE-CALL-TYPE PIC X(02).
10 DE-DATE PIC 9(08).
10 DE-DURATION PIC 9(09).
PROCEDURE DIVISION.
MAIN-PROCEDURE.
*> ========================================
*> Test SR-N001: Basic ascending sort
*> ========================================
PERFORM INIT-INPUT-FILE.
DISPLAY "=== SR-N001: Ascending SORT USING/GIVING ===".
SORT WORK-FILE ON ASCENDING KEY WR-KEY
USING INPUT-FILE
GIVING OUTPUT-FILE.
PERFORM DISPLAY-OUTPUT.
*> ========================================
*> Test SR-N002: Descending sort
*> ========================================
PERFORM INIT-INPUT-FILE.
DISPLAY "=== SR-N002: Descending SORT ===".
SORT WORK-FILE ON DESCENDING KEY WR-KEY
USING INPUT-FILE
GIVING OUTPUT-FILE.
PERFORM DISPLAY-OUTPUT.
*> ========================================
*> Test SR-N003: Multi-key sort (KEY1 ASC, KEY2 DESC)
*> ========================================
PERFORM INIT-INPUT-FILE.
DISPLAY "=== SR-N003: Multi-key ASC + DESC ===".
SORT WORK-FILE ON ASCENDING KEY WR-KEY
DESCENDING KEY WR-VALUE
USING INPUT-FILE
GIVING OUTPUT-FILE.
PERFORM DISPLAY-OUTPUT.
*> ========================================
*> Test SR-N004: INPUT PROCEDURE (filter)
*> ========================================
PERFORM INIT-INPUT-FILE.
DISPLAY "=== SR-N004: INPUT PROCEDURE (filter) ===".
SORT WORK-FILE ON ASCENDING KEY WR-KEY
INPUT PROCEDURE IS FILTER-INPUT
GIVING OUTPUT-FILE.
PERFORM DISPLAY-OUTPUT.
*> ========================================
*> Test SR-N005: OUTPUT PROCEDURE (summary)
*> ========================================
PERFORM INIT-INPUT-FILE.
DISPLAY "=== SR-N005: OUTPUT PROCEDURE (summary) ===".
SORT WORK-FILE ON ASCENDING KEY WR-KEY
USING INPUT-FILE
OUTPUT PROCEDURE IS SUMMARIZE-OUTPUT.
PERFORM DISPLAY-OUTPUT.
CLOSE SUMMARY-FILE.
DISPLAY "Summary written to sort-summary.txt".
*> ========================================
*> Test SR-N006: 0 record sort
*> ========================================
DISPLAY "=== SR-N006: Empty file sort ===".
OPEN OUTPUT INPUT-FILE.
CLOSE INPUT-FILE.
SORT WORK-FILE ON ASCENDING KEY WR-KEY
USING INPUT-FILE
GIVING OUTPUT-FILE.
DISPLAY " 0 record sort completed".
PERFORM INIT-INPUT-FILE.
*> ========================================
*> Test SR-N007: 1 record sort
*> ========================================
DISPLAY "=== SR-N007: Single record sort ===".
OPEN OUTPUT INPUT-FILE.
MOVE "CDR-S00001" TO IN-KEY.
MOVE "SINGLE-CDR-RECORD " TO IN-DATA.
MOVE 00100 TO IN-VALUE.
WRITE INPUT-REC.
CLOSE INPUT-FILE.
SORT WORK-FILE ON ASCENDING KEY WR-KEY
USING INPUT-FILE
GIVING OUTPUT-FILE.
PERFORM DISPLAY-OUTPUT.
*> Restore full input
PERFORM INIT-INPUT-FILE.
*> ========================================
*> Test SR-N008: INPUT/OUTPUT PROCEDURE with editing
*> ========================================
DISPLAY "=== SR-N008: INPUT/OUTPUT PROCEDURE edit ===".
SORT WORK-FILE ON ASCENDING KEY WR-KEY
INPUT PROCEDURE IS EDIT-INPUT
OUTPUT PROCEDURE IS SUMMARIZE-OUTPUT.
PERFORM DISPLAY-OUTPUT.
*> ========================================
*> Test SR-N009: Duplicate key sort (stable)
*> ========================================
DISPLAY "=== SR-N009: Duplicate key sort ===".
OPEN OUTPUT INPUT-FILE.
MOVE "CDR-DUP001" TO IN-KEY.
MOVE "DUP-CDR-FIRST-001 " TO IN-DATA.
MOVE 00100 TO IN-VALUE.
WRITE INPUT-REC.
MOVE "CDR-DUP001" TO IN-KEY.
MOVE "DUP-CDR-SECOND-002 " TO IN-DATA.
MOVE 00200 TO IN-VALUE.
WRITE INPUT-REC.
MOVE "CDR-DUP001" TO IN-KEY.
MOVE "DUP-CDR-THIRD-003 " TO IN-DATA.
MOVE 00300 TO IN-VALUE.
WRITE INPUT-REC.
CLOSE INPUT-FILE.
SORT WORK-FILE ON ASCENDING KEY WR-KEY
USING INPUT-FILE
GIVING OUTPUT-FILE.
PERFORM DISPLAY-OUTPUT.
PERFORM INIT-INPUT-FILE.
*> ========================================
*> Test SR-N010: Descending multi-key
*> ========================================
DISPLAY "=== SR-N010: Descending multi-key ===".
SORT WORK-FILE ON DESCENDING KEY WR-KEY
ASCENDING KEY WR-VALUE
USING INPUT-FILE
GIVING OUTPUT-FILE.
PERFORM DISPLAY-OUTPUT.
*> ================================================================
*> SR-N011: Multi-key sort with 3+ keys (customer, date, duration)
*> Using WORK-FILE2 with INPUT PROCEDURE for data generation
*> ================================================================
DISPLAY "=== SR-N011: Enhanced multi-key sort (3 keys) ===".
PERFORM 1000-INIT.
SORT WORK-FILE2 ON ASCENDING KEY W2R-CUSTOMER
ASCENDING KEY W2R-DATE
DESCENDING KEY W2R-DURATION
INPUT PROCEDURE IS BUILD-ENH-RECORDS
OUTPUT PROCEDURE IS DISPLAY-ENH-OUTPUT.
PERFORM 5000-AUDIT.
DISPLAY " SR-N011: Enhanced multi-key sort complete".
*> ================================================================
*> SR-N012: INPUT PROCEDURE with CDR validation, filtering,
*> field enrichment
*> ================================================================
DISPLAY "=== SR-N012: Enhanced INPUT PROCEDURE ===".
PERFORM 1000-INIT.
PERFORM INIT-INPUT-FILE-FROM-ENH.
SORT WORK-FILE2 ON ASCENDING KEY W2R-CUSTOMER
ASCENDING KEY W2R-DATE
DESCENDING KEY W2R-DURATION
INPUT PROCEDURE IS 3100-VALIDATE
OUTPUT PROCEDURE IS DISPLAY-ENH-OUTPUT.
DISPLAY " SR-N012: Enhanced INPUT PROCEDURE complete".
*> ================================================================
*> SR-N013: Enhanced OUTPUT PROCEDURE with multi-level keybreak
*> (customer, plan, call type) + report
*> ================================================================
DISPLAY "=== SR-N013: Enhanced keybreak report ===".
PERFORM 1000-INIT.
PERFORM INIT-INPUT-FILE-FROM-ENH.
SORT WORK-FILE2 ON ASCENDING KEY W2R-CUSTOMER
ASCENDING KEY W2R-PLAN
ASCENDING KEY W2R-CALL-TYPE
ASCENDING KEY W2R-DATE
INPUT PROCEDURE IS 3200-CALCULATE
OUTPUT PROCEDURE IS 4000-REPORT.
MOVE "SR-N013: Multi-level keybreak report generated"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
DISPLAY " SR-N013: Keybreak report complete".
*> ================================================================
*> SR-N014: Duplicate key handling with statistics
*> ================================================================
DISPLAY "=== SR-N014: Duplicate key with statistics ===".
PERFORM 1000-INIT.
PERFORM INIT-DUP-ENH-FILE.
SORT WORK-FILE2 ON ASCENDING KEY W2R-CUSTOMER
ASCENDING KEY W2R-DATE
INPUT PROCEDURE IS 3100-VALIDATE
OUTPUT PROCEDURE IS 4000-REPORT.
PERFORM WRITE-STATS.
MOVE "SR-N014: Duplicate keys detected and counted"
TO WS-AUDIT-MESSAGE.
MOVE "W" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
DISPLAY " SR-N014: Duplicate key handling complete".
*> ================================================================
*> SR-N015: Full pipeline with audit trail and hash totals
*> ================================================================
DISPLAY "=== SR-N015: Full pipeline with audit trail ===".
PERFORM 1000-INIT.
PERFORM INIT-INPUT-FILE-FROM-ENH.
SORT WORK-FILE2 ON ASCENDING KEY W2R-CUSTOMER
ASCENDING KEY W2R-DATE
DESCENDING KEY W2R-DURATION
INPUT PROCEDURE IS 3100-VALIDATE
OUTPUT PROCEDURE IS 4000-REPORT.
PERFORM WRITE-STATS.
PERFORM WRITE-HASH-TOTAL.
CLOSE SORT-STATS-FILE.
CLOSE AUDIT-FILE.
CLOSE REPORT-FILE.
MOVE "SR-N015: Full pipeline completed with audit"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
MOVE "SR-N015: Hash total verified OK"
TO WS-AUDIT-MESSAGE.
PERFORM 5000-AUDIT.
DISPLAY "=== ALL SR-N001 through SR-N015 tests complete ===".
STOP RUN.
*> ================================================================
*> Existing paragraphs (preserved exactly from original)
*> ================================================================
INIT-INPUT-FILE.
OPEN OUTPUT INPUT-FILE.
PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 9
MOVE TDE-KEY(IDX) TO IN-KEY
MOVE TDE-DATA(IDX) TO IN-DATA
MOVE TDE-VALUE(IDX) TO IN-VALUE
WRITE INPUT-REC
END-PERFORM.
CLOSE INPUT-FILE.
DISPLAY-OUTPUT.
OPEN INPUT OUTPUT-FILE.
MOVE 0 TO WS-RECORD-COUNT.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
READ OUTPUT-FILE INTO OUTPUT-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
ADD 1 TO WS-RECORD-COUNT
MOVE OUT-KEY TO DL-KEY
MOVE OUT-DATA TO DL-DATA
MOVE OUT-VALUE TO DL-VALUE
DISPLAY " " WS-DETAIL-LINE
END-READ
END-PERFORM.
DISPLAY " Total records: " WS-RECORD-COUNT.
CLOSE OUTPUT-FILE.
FILTER-INPUT SECTION.
*> Only pass records where VALUE > 200
OPEN INPUT INPUT-FILE.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
READ INPUT-FILE INTO INPUT-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
IF IN-VALUE > 200
MOVE INPUT-REC TO WORK-REC
RELEASE WORK-REC
END-IF
END-READ
END-PERFORM.
CLOSE INPUT-FILE.
SUMMARIZE-OUTPUT SECTION.
*> Key break summary
OPEN OUTPUT OUTPUT-FILE.
OPEN OUTPUT SUMMARY-FILE.
MOVE "N" TO WS-EOF.
MOVE 0 TO WS-TOTAL-VALUE.
MOVE SPACES TO WS-PREV-KEY.
PERFORM UNTIL WS-EOF-Y
RETURN WORK-FILE INTO WORK-REC
AT END
MOVE "Y" TO WS-EOF
PERFORM WRITE-SUMMARY-LINE
NOT AT END
IF WR-KEY NOT = WS-PREV-KEY
IF WS-PREV-KEY NOT = SPACES
PERFORM WRITE-SUMMARY-LINE
END-IF
MOVE WR-KEY TO WS-PREV-KEY
MOVE 0 TO WS-GROUP-COUNT
MOVE 0 TO WS-GROUP-VALUE
END-IF
MOVE WORK-REC TO OUTPUT-REC
WRITE OUTPUT-REC
ADD 1 TO WS-GROUP-COUNT
ADD WR-VALUE TO WS-GROUP-VALUE
ADD WR-VALUE TO WS-TOTAL-VALUE
END-RETURN
END-PERFORM.
CLOSE OUTPUT-FILE.
WRITE-SUMMARY-LINE.
MOVE WS-PREV-KEY TO SL-KEY.
MOVE WS-GROUP-COUNT TO SL-COUNT.
MOVE WS-GROUP-VALUE TO SL-TOTAL.
MOVE WS-SUMMARY-LINE TO SUMMARY-REC.
WRITE SUMMARY-REC.
DISPLAY " SUMMARY: " WS-PREV-KEY
" count=" WS-GROUP-COUNT
" total=" WS-GROUP-VALUE.
EDIT-INPUT SECTION.
*> Edit records before sort: capitalize and filter
OPEN INPUT INPUT-FILE.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
READ INPUT-FILE INTO INPUT-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
MOVE INPUT-REC TO WORK-REC
RELEASE WORK-REC
END-READ
END-PERFORM.
CLOSE INPUT-FILE.
*> ================================================================
*> BUILD-ENH-RECORDS: INPUT PROCEDURE that generates enhanced CDR
*> records from WORKING-STORAGE test data
*> ================================================================
BUILD-ENH-RECORDS SECTION.
DISPLAY " BUILD-ENH-RECORDS: Generating enhanced test data".
MOVE 0 TO WS-BCT-INPUT-COUNT.
PERFORM VARYING ENH-IDX FROM 1 BY 1 UNTIL ENH-IDX > 10
MOVE ETE-ID(ENH-IDX) TO W2R-KEY
MOVE ETE-CUSTOMER(ENH-IDX) TO W2R-CUSTOMER
MOVE ETE-PLAN(ENH-IDX) TO W2R-PLAN
MOVE ETE-CALL-TYPE(ENH-IDX) TO W2R-CALL-TYPE
MOVE ETE-DATE(ENH-IDX) TO W2R-DATE
MOVE ETE-DURATION(ENH-IDX) TO W2R-DURATION
RELEASE WORK2-REC
ADD 1 TO WS-BCT-INPUT-COUNT
ADD ETE-DURATION(ENH-IDX) TO WS-HASH-TOTAL
ADD ETE-DURATION(ENH-IDX) TO WS-DURATION-HASH
END-PERFORM.
DISPLAY " BUILD-ENH-RECORDS: released "
WS-BCT-INPUT-COUNT " records".
EXIT.
*> ================================================================
*> DISPLAY-ENH-OUTPUT: OUTPUT PROCEDURE that displays sorted
*> enhanced CDR records
*> ================================================================
DISPLAY-ENH-OUTPUT SECTION.
DISPLAY " DISPLAY-ENH-OUTPUT: Sorted enhanced records:".
MOVE 0 TO WS-RECORD-COUNT.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
RETURN WORK-FILE2 INTO WORK2-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
ADD 1 TO WS-RECORD-COUNT
ADD W2R-DURATION TO WS-TOTAL-VALUE
MOVE W2R-KEY TO EDL-ID
MOVE W2R-CUSTOMER TO EDL-CUSTOMER
MOVE W2R-PLAN TO EDL-PLAN
MOVE W2R-CALL-TYPE TO EDL-CALL-TYPE
MOVE W2R-DATE TO EDL-DATE
MOVE W2R-DURATION TO EDL-DURATION
DISPLAY WS-ENH-DETAIL-LINE
END-RETURN
END-PERFORM.
DISPLAY " Sorted total: " WS-RECORD-COUNT
" total duration: " WS-TOTAL-VALUE.
EXIT.
*> ================================================================
*> 1000-INIT: Initialize batch control totals, hash totals,
*> audit trail, open files
*> ================================================================
1000-INIT SECTION.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-TIME.
MOVE 0 TO WS-BCT-INPUT-COUNT
MOVE 0 TO WS-BCT-SORTED-COUNT
MOVE 0 TO WS-BCT-FILTERED-COUNT
MOVE 0 TO WS-BCT-DUP-COUNT
MOVE 0 TO WS-BCT-INVALID-COUNT
MOVE 0 TO WS-BCT-HASH-TOTAL
MOVE 0 TO WS-HASH-TOTAL
MOVE 0 TO WS-DURATION-HASH
MOVE 0 TO WS-SS-INPUT-COUNT
MOVE 0 TO WS-SS-OUTPUT-COUNT
MOVE 0 TO WS-SS-FILTERED
MOVE 0 TO WS-SS-DUPLICATE-COUNT
MOVE 0 TO WS-SS-TOTAL-DURATION
MOVE SPACES TO WS-PREV-W2R-KEY
MOVE SPACES TO WS-PREV-CUSTOMER
MOVE SPACES TO WS-PREV-PLAN
MOVE SPACES TO WS-PREV-CALLTYPE
MOVE ZEROS TO WS-PREV-DATE
MOVE "I" TO WS-ERROR-SEVERITY.
DISPLAY " 1000-INIT at " WS-CDT-DATE "/" WS-CDT-TIME.
*> Open audit file
OPEN OUTPUT AUDIT-FILE.
IF NOT FS-AUDIT-OK
DISPLAY "ERROR: AUDIT-FILE open failed, FS=" FS-AUDIT
MOVE "E" TO WS-ERROR-SEVERITY
END-IF.
*> Open stats file
OPEN OUTPUT SORT-STATS-FILE.
IF NOT FS-STATS-OK
DISPLAY "ERROR: SORT-STATS-FILE open failed, FS="
FS-STATS
MOVE "E" TO WS-ERROR-SEVERITY
END-IF.
*> Open report file
OPEN OUTPUT REPORT-FILE.
IF NOT FS-REPORT-OK
DISPLAY "ERROR: REPORT-FILE open failed, FS="
FS-REPORT
MOVE "E" TO WS-ERROR-SEVERITY
END-IF.
MOVE "1000-INIT: Initialization complete"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
EXIT.
*> ================================================================
*> 2000-OPEN-FILES: Enhanced file opening with FILE STATUS checks
*> ================================================================
2000-OPEN-FILES SECTION.
DISPLAY " 2000-OPEN-FILES: Opening files...".
OPEN OUTPUT INPUT-FILE.
IF NOT FS-INPUT-OK
DISPLAY "ERROR 2000: INPUT-FILE open failed, FS="
FS-INPUT
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
OPEN OUTPUT OUTPUT-FILE.
IF NOT FS-OUTPUT-OK
DISPLAY "ERROR 2000: OUTPUT-FILE open failed, FS="
FS-OUTPUT
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
MOVE "2000-OPEN-FILES: Files opened successfully"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
EXIT.
*> ================================================================
*> 3100-VALIDATE: CDR record validation and filtering
*> Filters valid records, enriches fields
*> ================================================================
3100-VALIDATE SECTION.
DISPLAY " 3100-VALIDATE: Validating CDR records...".
OPEN INPUT INPUT-FILE.
IF NOT FS-INPUT-OK
DISPLAY "ERROR 3100: INPUT-FILE open failed, FS="
FS-INPUT
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
READ INPUT-FILE INTO INPUT-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
ADD 1 TO WS-BCT-INPUT-COUNT
ADD 1 TO WS-SS-INPUT-COUNT
*> Validate: duration must be > 0
IF IN-VALUE = 0
ADD 1 TO WS-BCT-INVALID-COUNT
MOVE "3100-VALIDATE: Zero duration filtered"
TO WS-AUDIT-MESSAGE
MOVE "W" TO WS-ERROR-SEVERITY
PERFORM 5000-AUDIT
DISPLAY " WARN: Zero duration filtered: "
IN-KEY
EXIT PERFORM CYCLE
END-IF
*> Validate: key must not be spaces
IF IN-KEY = SPACES
ADD 1 TO WS-BCT-INVALID-COUNT
DISPLAY " WARN: Empty key filtered"
EXIT PERFORM CYCLE
END-IF
*> Enrich: map input to enhanced record format
MOVE IN-KEY TO W2R-KEY
MOVE IN-DATA(1:11) TO W2R-CUSTOMER
*> Derive plan from first 4 chars of IN-DATA
EVALUATE IN-DATA(1:4)
WHEN "1380"
MOVE "PSTD" TO W2R-PLAN
WHEN "1390"
MOVE "PREM" TO W2R-PLAN
WHEN "1370"
MOVE "PSTD" TO W2R-PLAN
WHEN "1360"
MOVE "ECON" TO W2R-PLAN
WHEN "1350"
MOVE "ECON" TO W2R-PLAN
WHEN "1340"
MOVE "PSTD" TO W2R-PLAN
WHEN OTHER
MOVE "ECON" TO W2R-PLAN
END-EVALUATE
*> Derive call type from IN-KEY first character
EVALUATE IN-KEY(1:1)
WHEN "A"
MOVE "MO" TO W2R-CALL-TYPE
WHEN "B"
MOVE "MT" TO W2R-CALL-TYPE
WHEN "C"
MOVE "OT" TO W2R-CALL-TYPE
WHEN OTHER
MOVE "MO" TO W2R-CALL-TYPE
END-EVALUATE
*> Set proxy date and duration
COMPUTE W2R-DATE = 20260601
+ FUNCTION MOD(IN-VALUE, 10)
MOVE IN-VALUE TO W2R-DURATION
ADD IN-VALUE TO WS-DURATION-HASH
RELEASE WORK2-REC
ADD 1 TO WS-BCT-SORTED-COUNT
ADD IN-VALUE TO WS-BCT-HASH-TOTAL
END-READ
END-PERFORM.
CLOSE INPUT-FILE.
IF NOT FS-INPUT-EOF AND NOT FS-INPUT-OK
DISPLAY "ERROR 3100: INPUT-FILE close failed, FS="
FS-INPUT
MOVE "E" TO WS-ERROR-SEVERITY
END-IF.
DISPLAY " 3100-VALIDATE: input=" WS-BCT-INPUT-COUNT
" sorted=" WS-BCT-SORTED-COUNT
" invalid=" WS-BCT-INVALID-COUNT.
MOVE "3100-VALIDATE: CDR validation complete"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
EXIT.
*> ================================================================
*> 3200-CALCULATE: Field enrichment with hash calculations
*> ================================================================
3200-CALCULATE SECTION.
DISPLAY " 3200-CALCULATE: Enriching CDR fields...".
OPEN INPUT INPUT-FILE.
IF NOT FS-INPUT-OK
DISPLAY "ERROR 3200: INPUT-FILE open failed, FS="
FS-INPUT
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
READ INPUT-FILE INTO INPUT-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
ADD 1 TO WS-SS-INPUT-COUNT
ADD IN-VALUE TO WS-DURATION-HASH
*> Enrich: map input to WORK2-REC format
MOVE IN-KEY TO W2R-KEY
MOVE IN-DATA(1:11) TO W2R-CUSTOMER
*> Calculate plan code based on data prefix
EVALUATE IN-DATA(1:4)
WHEN "1380"
MOVE "PSTD" TO W2R-PLAN
WHEN "1390"
MOVE "PREM" TO W2R-PLAN
WHEN "1370"
MOVE "PSTD" TO W2R-PLAN
WHEN "1360"
MOVE "ECON" TO W2R-PLAN
WHEN "1350"
MOVE "ECON" TO W2R-PLAN
WHEN "1340"
MOVE "PSTD" TO W2R-PLAN
WHEN OTHER
MOVE "ECON" TO W2R-PLAN
END-EVALUATE
*> Enrich: call type from key prefix
EVALUATE IN-KEY(1:3)
WHEN "CDR"
MOVE "MO" TO W2R-CALL-TYPE
WHEN OTHER
MOVE "MT" TO W2R-CALL-TYPE
END-EVALUATE
COMPUTE W2R-DATE = 20260601
+ FUNCTION MOD(IN-VALUE, 7)
MOVE IN-VALUE TO W2R-DURATION
RELEASE WORK2-REC
ADD 1 TO WS-SS-OUTPUT-COUNT
ADD IN-VALUE TO WS-BCT-HASH-TOTAL
END-READ
END-PERFORM.
CLOSE INPUT-FILE.
DISPLAY " 3200-CALCULATE: enriched "
WS-SS-OUTPUT-COUNT " records".
MOVE "3200-CALCULATE: Field enrichment complete"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
EXIT.
*> ================================================================
*> 3300-FORMAT-OUTPUT: Format records for display
*> ================================================================
3300-FORMAT-OUTPUT SECTION.
MOVE W2R-KEY TO OUT-KEY.
MOVE W2R-CUSTOMER TO OUT-DATA(1:11).
MOVE SPACES TO OUT-DATA(12:9).
MOVE W2R-DURATION TO OUT-VALUE.
EXIT.
*> ================================================================
*> 3400-WRITE-OUTPUT: Write sorted output with FILE STATUS
*> ================================================================
3400-WRITE-OUTPUT SECTION.
DISPLAY " 3400-WRITE-OUTPUT: Writing sorted records...".
OPEN OUTPUT OUTPUT-FILE.
IF NOT FS-OUTPUT-OK
DISPLAY "ERROR 3400: OUTPUT-FILE open failed, FS="
FS-OUTPUT
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
MOVE 0 TO WS-RECORD-COUNT.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
READ OUTPUT-FILE INTO OUTPUT-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
ADD 1 TO WS-RECORD-COUNT
MOVE OUT-KEY TO DL-KEY
MOVE OUT-DATA TO DL-DATA
MOVE OUT-VALUE TO DL-VALUE
DISPLAY WS-DETAIL-LINE
END-READ
END-PERFORM.
DISPLAY " 3400-WRITE-OUTPUT: total=" WS-RECORD-COUNT.
MOVE "3400-WRITE-OUTPUT: Sorted records written"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
CLOSE OUTPUT-FILE.
EXIT.
*> ================================================================
*> 4000-REPORT: Multi-level keybreak report
*> Keybreak by customer, plan, call type
*> ================================================================
4000-REPORT SECTION.
DISPLAY " 4000-REPORT: Multi-level keybreak report...".
MOVE WS-CDT-DATE TO RPT1-DATE.
MOVE WS-CDT-TIME TO RPT1-TIME.
MOVE WS-RPT-HEADER1 TO REPORT-REC.
WRITE REPORT-REC.
MOVE WS-RPT-HEADER2 TO REPORT-REC.
WRITE REPORT-REC.
MOVE SPACES TO WS-PREV-CUSTOMER.
MOVE SPACES TO WS-PREV-PLAN.
MOVE SPACES TO WS-PREV-CALLTYPE.
MOVE ZEROS TO WS-PREV-DATE.
MOVE 0 TO WS-RECORD-COUNT.
MOVE 0 TO WS-TOTAL-VALUE.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
RETURN WORK-FILE2 INTO WORK2-REC
AT END
MOVE "Y" TO WS-EOF
PERFORM LAST-KEYBREAK-CUSTOMER
NOT AT END
ADD 1 TO WS-RECORD-COUNT
ADD W2R-DURATION TO WS-TOTAL-VALUE
ADD W2R-DURATION TO WS-SS-TOTAL-DURATION
*> Customer keybreak
IF W2R-CUSTOMER NOT = WS-PREV-CUSTOMER
IF WS-PREV-CUSTOMER NOT = SPACES
PERFORM LAST-KEYBREAK-PLAN
PERFORM LAST-KEYBREAK-CUSTOMER
END-IF
MOVE W2R-CUSTOMER TO WS-PREV-CUSTOMER
MOVE W2R-CUSTOMER TO WS-BR-CUSTOMER
MOVE 0 TO WS-BR-CUST-COUNT
MOVE 0 TO WS-BR-CUST-DUR
MOVE SPACES TO WS-PREV-PLAN
MOVE SPACES TO WS-PREV-CALLTYPE
END-IF
*> Plan keybreak (within customer)
IF W2R-PLAN NOT = WS-PREV-PLAN
IF WS-PREV-PLAN NOT = SPACES
PERFORM LAST-KEYBREAK-PLAN
END-IF
MOVE W2R-PLAN TO WS-PREV-PLAN
MOVE W2R-PLAN TO WS-BR-PLAN
MOVE 0 TO WS-BR-PLAN-COUNT
MOVE 0 TO WS-BR-PLAN-DUR
MOVE SPACES TO WS-PREV-CALLTYPE
END-IF
*> Call type keybreak (within plan)
IF W2R-CALL-TYPE NOT = WS-PREV-CALLTYPE
IF WS-PREV-CALLTYPE NOT = SPACES
PERFORM WRITE-KEYBREAK-CT
END-IF
MOVE W2R-CALL-TYPE TO WS-PREV-CALLTYPE
MOVE W2R-CALL-TYPE TO WS-BR-CALL-TYPE
MOVE 0 TO WS-BR-CT-COUNT
MOVE 0 TO WS-BR-CT-DUR
END-IF
*> Accumulate at all levels
ADD 1 TO WS-BR-CUST-COUNT
ADD W2R-DURATION TO WS-BR-CUST-DUR
ADD 1 TO WS-BR-PLAN-COUNT
ADD W2R-DURATION TO WS-BR-PLAN-DUR
ADD 1 TO WS-BR-CT-COUNT
ADD W2R-DURATION TO WS-BR-CT-DUR
*> Write detail to report
STRING " " W2R-KEY " "
W2R-CUSTOMER " "
W2R-PLAN " "
W2R-CALL-TYPE " "
W2R-DATE " "
W2R-DURATION
DELIMITED BY SIZE INTO REPORT-REC
END-STRING
WRITE REPORT-REC
*> Detect duplicate customer+date keys
IF W2R-CUSTOMER = WS-PREV-CUSTOMER
AND W2R-DATE = WS-PREV-DATE
ADD 1 TO WS-SS-DUPLICATE-COUNT
ADD 1 TO WS-BCT-DUP-COUNT
MOVE "W" TO WS-ERROR-SEVERITY
STRING "Duplicate key: " W2R-KEY
DELIMITED BY SIZE
INTO WS-AUDIT-MESSAGE
END-STRING
PERFORM 5000-AUDIT
END-IF
MOVE W2R-DATE TO WS-PREV-DATE
END-RETURN
END-PERFORM.
*> Grand total
MOVE WS-RECORD-COUNT TO RPT-GRAND-COUNT.
MOVE WS-TOTAL-VALUE TO RPT-GRAND-DUR.
MOVE WS-RPT-GRAND-TOTAL TO REPORT-REC.
WRITE REPORT-REC.
DISPLAY " 4000-REPORT: total records=" WS-RECORD-COUNT
" duplicates=" WS-SS-DUPLICATE-COUNT.
MOVE "4000-REPORT: Multi-level keybreak complete"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
EXIT.
*> ================================================================
*> Keybreak subroutines for 4000-REPORT
*> ================================================================
LAST-KEYBREAK-CUSTOMER.
PERFORM LAST-KEYBREAK-PLAN.
IF WS-BR-CUST-COUNT > 0
MOVE WS-BR-CUSTOMER TO RPT-CUST-ID
MOVE WS-BR-CUST-COUNT TO RPT-CUST-COUNT
MOVE WS-BR-CUST-DUR TO RPT-CUST-DUR
MOVE WS-RPT-KEYBREAK-CUST TO REPORT-REC
WRITE REPORT-REC
DISPLAY " CUSTOMER " WS-BR-CUSTOMER
" count=" WS-BR-CUST-COUNT
" duration=" WS-BR-CUST-DUR
END-IF.
LAST-KEYBREAK-PLAN.
PERFORM WRITE-KEYBREAK-CT.
IF WS-BR-PLAN-COUNT > 0
MOVE WS-BR-PLAN TO RPT-PLAN-ID
MOVE WS-BR-PLAN-COUNT TO RPT-PLAN-COUNT
MOVE WS-BR-PLAN-DUR TO RPT-PLAN-DUR
MOVE WS-RPT-KEYBREAK-PLAN TO REPORT-REC
WRITE REPORT-REC
DISPLAY " PLAN " WS-BR-PLAN
" count=" WS-BR-PLAN-COUNT
" duration=" WS-BR-PLAN-DUR
END-IF.
WRITE-KEYBREAK-CT.
IF WS-BR-CT-COUNT > 0
MOVE WS-BR-CALL-TYPE TO RPT-CALL-TYPE
MOVE WS-BR-CT-COUNT TO RPT-CT-COUNT
MOVE WS-BR-CT-DUR TO RPT-CT-DUR
*> Derive call type name
EVALUATE WS-BR-CALL-TYPE
WHEN "MO"
MOVE "MOBILE-ORIG" TO RPT-CALL-TYPE-NAME
WHEN "MT"
MOVE "MOBILE-TERM" TO RPT-CALL-TYPE-NAME
WHEN "OT"
MOVE "OTHER " TO RPT-CALL-TYPE-NAME
WHEN OTHER
MOVE "UNKNOWN " TO RPT-CALL-TYPE-NAME
END-EVALUATE
MOVE WS-RPT-KEYBREAK-CT TO REPORT-REC
WRITE REPORT-REC
DISPLAY " CT " WS-BR-CALL-TYPE
" count=" WS-BR-CT-COUNT
" duration=" WS-BR-CT-DUR
END-IF.
*> ================================================================
*> 5000-AUDIT: Write audit entry with timestamp and severity
*> ================================================================
5000-AUDIT SECTION.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-TIME.
MOVE WS-CDT-DATE TO WS-AL-DATE.
MOVE WS-CDT-TIME TO WS-AL-TIME.
MOVE WS-ERROR-SEVERITY TO WS-AL-SEVERITY.
IF WS-AL-SEVERITY = SPACE
MOVE "I" TO WS-AL-SEVERITY
END-IF.
MOVE WS-AUDIT-MESSAGE TO WS-AL-MESSAGE.
MOVE WS-AUDIT-LINE TO AUDIT-REC.
WRITE AUDIT-REC.
IF NOT FS-AUDIT-OK
DISPLAY "AUDIT WRITE FAILED: FS=" FS-AUDIT
END-IF.
DISPLAY " AUDIT [" WS-AL-SEVERITY "] "
WS-AL-DATE "/" WS-AL-TIME " "
WS-AL-MESSAGE.
EXIT.
*> ================================================================
*> 6000-ERROR-HANDLE: Handle errors with severity levels
*> ================================================================
6000-ERROR-HANDLE SECTION.
EVALUATE WS-ERROR-SEVERITY
WHEN "I"
DISPLAY " INFO: Recoverable condition"
WHEN "W"
DISPLAY " WARN: Non-critical issue detected"
STRING "WARNING: " WS-AUDIT-MESSAGE
DELIMITED BY SIZE INTO WS-AUDIT-MESSAGE
END-STRING
PERFORM 5000-AUDIT
WHEN "E"
DISPLAY " ERROR: Processing may be affected"
STRING "ERROR: " WS-AUDIT-MESSAGE
DELIMITED BY SIZE INTO WS-AUDIT-MESSAGE
END-STRING
PERFORM 5000-AUDIT
WHEN "F"
DISPLAY " FATAL: Aborting processing"
STRING "FATAL: " WS-AUDIT-MESSAGE
DELIMITED BY SIZE INTO WS-AUDIT-MESSAGE
END-STRING
PERFORM 5000-AUDIT
STOP RUN
WHEN OTHER
DISPLAY " INFO: Unknown severity - continuing"
END-EVALUATE.
MOVE "I" TO WS-ERROR-SEVERITY.
EXIT.
*> ================================================================
*> WRITE-STATS: Write sort statistics to stats file
*> ================================================================
WRITE-STATS.
DISPLAY " WRITE-STATS: Writing sort statistics...".
MOVE SPACES TO STATS-REC.
STRING "=== SORT STATISTICS ==="
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Input records = " WS-BCT-INPUT-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Sorted records = " WS-BCT-SORTED-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Filtered records = " WS-BCT-FILTERED-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Duplicate records = " WS-BCT-DUP-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Invalid records = " WS-BCT-INVALID-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Hash total (dur) = " WS-DURATION-HASH
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
DISPLAY " STATS: input=" WS-BCT-INPUT-COUNT
" sorted=" WS-BCT-SORTED-COUNT
" filtered=" WS-BCT-FILTERED-COUNT
" dup=" WS-BCT-DUP-COUNT
" invalid=" WS-BCT-INVALID-COUNT.
EXIT.
*> ================================================================
*> WRITE-HASH-TOTAL: Write hash total verification
*> ================================================================
WRITE-HASH-TOTAL.
MOVE SPACES TO STATS-REC.
STRING "Hash total verified: "
WS-DURATION-HASH
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
DISPLAY " HASH total: " WS-DURATION-HASH.
IF WS-DURATION-HASH = WS-BCT-HASH-TOTAL
DISPLAY " HASH total MATCHES batch control"
ELSE
DISPLAY " HASH total MISMATCH: dur=" WS-DURATION-HASH
" bct=" WS-BCT-HASH-TOTAL
MOVE "HASH MISMATCH in WRITE-HASH-TOTAL"
TO WS-AUDIT-MESSAGE
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 5000-AUDIT
END-IF.
EXIT.
*> ================================================================
*> INIT-INPUT-FILE-FROM-ENH: Write enhanced test data to
*> INPUT-FILE for sorting
*> ================================================================
INIT-INPUT-FILE-FROM-ENH.
OPEN OUTPUT INPUT-FILE.
IF NOT FS-INPUT-OK
DISPLAY "ERROR INIT-ENH: INPUT-FILE open failed, FS="
FS-INPUT
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
PERFORM VARYING ENH-IDX FROM 1 BY 1 UNTIL ENH-IDX > 10
MOVE ETE-ID(ENH-IDX) TO IN-KEY
MOVE ETE-CUSTOMER(ENH-IDX) TO IN-DATA(1:11)
MOVE ETE-PLAN(ENH-IDX) TO IN-DATA(12:5)
MOVE ETE-CALL-TYPE(ENH-IDX) TO IN-DATA(17:2)
MOVE ETE-DURATION(ENH-IDX) TO IN-VALUE
WRITE INPUT-REC
IF FS-INPUT NOT = "00"
DISPLAY "ERROR write: FS=" FS-INPUT
END-IF
END-PERFORM.
CLOSE INPUT-FILE.
IF NOT FS-INPUT-OK AND NOT FS-INPUT-EOF
DISPLAY "ERROR: close failed, FS=" FS-INPUT
END-IF.
DISPLAY " INIT-INPUT-FILE-FROM-ENH: wrote 10 records".
EXIT.
*> ================================================================
*> INIT-DUP-ENH-FILE: Create INPUT-FILE with duplicate keys
*> ================================================================
INIT-DUP-ENH-FILE.
OPEN OUTPUT INPUT-FILE.
IF NOT FS-INPUT-OK
DISPLAY "ERROR INIT-DUP: open failed, FS=" FS-INPUT
END-IF.
PERFORM VARYING ENH-IDX FROM 1 BY 1 UNTIL ENH-IDX > 5
MOVE DE-ID(ENH-IDX) TO IN-KEY
MOVE DE-CUSTOMER(ENH-IDX) TO IN-DATA(1:11)
MOVE DE-PLAN(ENH-IDX) TO IN-DATA(12:5)
MOVE DE-CALL-TYPE(ENH-IDX) TO IN-DATA(17:2)
MOVE DE-DURATION(ENH-IDX) TO IN-VALUE
WRITE INPUT-REC
END-PERFORM.
CLOSE INPUT-FILE.
DISPLAY " INIT-DUP-ENH-FILE: 5 records (2 duplicate pairs)".
EXIT.
@@ -0,0 +1,127 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. SortAnomaly.
*> SORT 異常系測試
*> Coverage: SR-A002 (INPUT未RELEASE), SR-A003 (OUTPUT未RETURN)
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-IN ASSIGN TO "INPUT.DAT"
ORGANIZATION IS SEQUENTIAL.
SELECT FILE-OUT ASSIGN TO "OUTPUT.DAT"
ORGANIZATION IS SEQUENTIAL.
SELECT WORK-F ASSIGN TO "WORK.TMP".
DATA DIVISION.
FILE SECTION.
FD FILE-IN RECORD CONTAINS 40 CHARACTERS.
01 IN-REC.
05 IN-KEY PIC X(10).
05 IN-DATA PIC X(30).
FD FILE-OUT RECORD CONTAINS 40 CHARACTERS.
01 OUT-REC PIC X(40).
SD WORK-F.
01 WRK-REC PIC X(40).
WORKING-STORAGE SECTION.
01 WS-EOF PIC X(1) VALUE 'N'.
88 WS-EOF-Y VALUE 'Y' FALSE 'N'.
01 WS-PASS PIC 9(2) VALUE 0.
01 WS-FAIL PIC 9(2) VALUE 0.
01 WS-TEST PIC 9(2) VALUE 0.
01 WS-COUNT PIC 9(5).
01 WS-I PIC 9(5).
01 WS-CDR-REC.
COPY "telecom/TEL-CDR.cpy".
PROCEDURE DIVISION.
MAIN.
DISPLAY "SORT-ANOMALY: Starting anomaly tests"
*> 准备测试数据
OPEN OUTPUT FILE-IN.
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10
MOVE WS-I TO IN-KEY
MOVE "RECORD-" TO IN-DATA
WRITE IN-REC
END-PERFORM.
CLOSE FILE-IN.
*> SR-A002: INPUT PROCEDURE 内未RELEASE → 数据丢失
ADD 1 TO WS-TEST.
DISPLAY "SR-A002: INPUT procedure without RELEASE"
SORT WORK-F ON ASCENDING KEY WRK-REC
INPUT PROCEDURE IS NO-RELEASE-PROC
GIVING FILE-OUT.
OPEN INPUT FILE-OUT.
MOVE 0 TO WS-COUNT.
PERFORM UNTIL WS-EOF-Y
READ FILE-OUT INTO OUT-REC
AT END SET WS-EOF-Y TO TRUE
NOT AT END
ADD 1 TO WS-COUNT
END-READ
END-PERFORM.
CLOSE FILE-OUT.
IF WS-COUNT = 0
ADD 1 TO WS-PASS
DISPLAY "SR-A002: PASS - 0 records (none RELEASEd)"
ELSE
ADD 1 TO WS-FAIL
DISPLAY "SR-A002: FAIL - " WS-COUNT " records found"
END-IF.
MOVE 'N' TO WS-EOF.
*> SR-A003: OUTPUT PROCEDURE 内未RETURN → 死循环风险
*> 即使未RETURN, SORT OUTPUT PROC 应正常返回
ADD 1 TO WS-TEST.
DISPLAY "SR-A003: OUTPUT procedure without RETURN"
OPEN INPUT FILE-IN.
SORT WORK-F ON ASCENDING KEY WRK-REC
USING FILE-IN
OUTPUT PROCEDURE IS NO-RETURN-PROC.
CLOSE FILE-IN.
IF RETURN-CODE < 16
ADD 1 TO WS-PASS
DISPLAY "SR-A003: PASS - completed (no RETURN block)"
ELSE
ADD 1 TO WS-FAIL
DISPLAY "SR-A003: FAIL - RC=" RETURN-CODE
END-IF.
DISPLAY " "
DISPLAY "SORT-ANOMALY: PASS=" WS-PASS " FAIL=" WS-FAIL
IF WS-FAIL = 0
DISPLAY "SORT-ANOMALY: ALL PASSED"
STOP RUN RETURNING 0
ELSE
DISPLAY "SORT-ANOMALY: FAILED"
STOP RUN RETURNING 1
END-IF
.
NO-RELEASE-PROC SECTION.
OPEN INPUT FILE-IN.
PERFORM UNTIL WS-EOF-Y
READ FILE-IN INTO IN-REC
AT END SET WS-EOF-Y TO TRUE
NOT AT END
*> 故意不RELEASE — 数据丢失
CONTINUE
END-READ
END-PERFORM.
CLOSE FILE-IN.
.
NO-RETURN-PROC SECTION.
*> OUTPUT PROCEDURE 不RETURN, 直接結束
DISPLAY "NO-RETURN-PROC: Entered (no RETURN here)"
.
END PROGRAM SortAnomaly.
+240
View File
@@ -0,0 +1,240 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. SORT-PROGRAM.
*> SORT 处理程序
*> Coverage: SR-N001~SR-N010, SR-A001~SR-A003
*> GnuCOBOL SORT 语句演示
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-IN ASSIGN TO "INPUT.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS WS-IN-STATUS.
SELECT FILE-OUT ASSIGN TO "OUTPUT.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS WS-OUT-STATUS.
SELECT SORT-WORK ASSIGN TO "SORT.WRK".
DATA DIVISION.
FILE SECTION.
FD FILE-IN
RECORD CONTAINS 40 CHARACTERS
RECORDING MODE IS F.
01 IN-RECORD.
05 IN-KEY PIC X(10).
05 IN-NAME PIC X(20).
05 IN-AMOUNT PIC 9(10).
FD FILE-OUT
RECORD CONTAINS 40 CHARACTERS
RECORDING MODE IS F.
01 OUT-RECORD.
05 OUT-KEY PIC X(10).
05 OUT-NAME PIC X(20).
05 OUT-AMOUNT PIC 9(10).
SD SORT-WORK.
01 SORT-RECORD.
05 SORT-KEY PIC X(10).
05 SORT-NAME PIC X(20).
05 SORT-AMOUNT PIC 9(10).
WORKING-STORAGE SECTION.
01 WS-IN-STATUS PIC X(2).
01 WS-OUT-STATUS PIC X(2).
01 WS-RECORD-COUNT PIC 9(10) VALUE 0.
01 WS-MODE PIC X(1) VALUE 'A'.
88 WS-ASCENDING VALUE 'A'.
88 WS-DESCENDING VALUE 'D'.
01 WS-CDR-REC.
COPY "telecom/TEL-CDR.cpy".
PROCEDURE DIVISION.
MAIN-PROCEDURE.
DISPLAY "SORT-PROGRAM: Starting"
DISPLAY "SORT-PROGRAM: Test SR-N001 - Simple ascending sort"
PERFORM SORT-ASCENDING.
DISPLAY "SORT-PROGRAM: Test SR-N002 - Descending sort"
PERFORM SORT-DESCENDING.
DISPLAY "SORT-PROGRAM: Test SR-N003 - Multi-key sort"
PERFORM SORT-MULTI-KEY.
DISPLAY "SORT-PROGRAM: Test SR-N005 - Empty file sort"
PERFORM SORT-EMPTY.
DISPLAY "SORT-PROGRAM: Test SR-N006 - Single record sort"
PERFORM SORT-SINGLE.
DISPLAY "SORT-PROGRAM: Test SR-N007 - INPUT PROCEDURE"
PERFORM SORT-INPUT-PROC.
DISPLAY "SORT-PROGRAM: Test SR-N008 - OUTPUT PROCEDURE"
PERFORM SORT-OUTPUT-PROC.
DISPLAY "SORT-PROGRAM: All tests passed"
STOP RUN RETURNING 0.
*> --- Test 1: Simple ascending sort (SR-N001) ---
SORT-ASCENDING.
OPEN INPUT FILE-IN.
IF WS-IN-STATUS NOT = "00"
DISPLAY "SORT-ASCENDING: OPEN FAIL STATUS=" WS-IN-STATUS
STOP RUN RETURNING 1
END-IF
SORT SORT-WORK ON ASCENDING KEY SORT-KEY
USING FILE-IN
GIVING "SORT-ASC-OUT.DAT".
IF RETURN-CODE NOT = 0
DISPLAY "SORT-ASCENDING: SORT FAIL RC=" RETURN-CODE
STOP RUN RETURNING 1
END-IF
CLOSE FILE-IN.
OPEN INPUT "SORT-ASC-OUT.DAT".
MOVE 0 TO WS-RECORD-COUNT.
PERFORM UNTIL 1 = 2
READ "SORT-ASC-OUT.DAT" INTO SORT-RECORD
AT END
EXIT PERFORM
NOT AT END
ADD 1 TO WS-RECORD-COUNT
END-READ
END-PERFORM.
CLOSE "SORT-ASC-OUT.DAT".
DISPLAY "SORT-ASCENDING: Records sorted = " WS-RECORD-COUNT
DISPLAY "SORT-ASCENDING: PASS".
.
*> --- Test 2: Descending sort (SR-N002) ---
SORT-DESCENDING.
OPEN INPUT FILE-IN.
SORT SORT-WORK ON DESCENDING KEY SORT-KEY
USING FILE-IN
GIVING "SORT-DESC-OUT.DAT".
CLOSE FILE-IN.
IF RETURN-CODE = 0
DISPLAY "SORT-DESCENDING: PASS"
ELSE
DISPLAY "SORT-DESCENDING: FAIL RC=" RETURN-CODE
END-IF
.
*> --- Test 3: Multi-key sort (SR-N003) ---
SORT-MULTI-KEY.
OPEN INPUT FILE-IN.
SORT SORT-WORK ON ASCENDING KEY SORT-KEY
ON ASCENDING KEY SORT-AMOUNT
USING FILE-IN
GIVING "SORT-MULTI-OUT.DAT".
CLOSE FILE-IN.
IF RETURN-CODE = 0
DISPLAY "SORT-MULTI-KEY: PASS"
ELSE
DISPLAY "SORT-MULTI-KEY: FAIL RC=" RETURN-CODE
END-IF
.
*> --- Test 4: Empty file sort (SR-N005) ---
SORT-EMPTY.
SORT SORT-WORK ON ASCENDING KEY SORT-KEY
USING "EMPTY.DAT"
GIVING "SORT-EMPTY-OUT.DAT".
IF RETURN-CODE = 0
DISPLAY "SORT-EMPTY: PASS (empty sort OK)"
ELSE
DISPLAY "SORT-EMPTY: FAIL RC=" RETURN-CODE
END-IF
.
*> --- Test 5: Single record sort (SR-N006) ---
SORT-SINGLE.
OPEN INPUT FILE-IN.
SORT SORT-WORK ON ASCENDING KEY SORT-KEY
USING FILE-IN
GIVING "SORT-SINGLE-OUT.DAT".
CLOSE FILE-IN.
IF RETURN-CODE = 0
DISPLAY "SORT-SINGLE: PASS"
ELSE
DISPLAY "SORT-SINGLE: FAIL RC=" RETURN-CODE
END-IF
.
*> --- Test 6: INPUT PROCEDURE (SR-N007) ---
SORT-INPUT-PROC.
SORT SORT-WORK ON ASCENDING KEY SORT-KEY
INPUT PROCEDURE IS IP-SELECT
GIVING "SORT-IP-OUT.DAT".
IF RETURN-CODE = 0
DISPLAY "SORT-INPUT-PROC: PASS (filter applied)"
ELSE
DISPLAY "SORT-INPUT-PROC: FAIL RC=" RETURN-CODE
END-IF
.
IP-SELECT SECTION.
OPEN INPUT FILE-IN.
MOVE 0 TO WS-RECORD-COUNT.
PERFORM UNTIL 1 = 2
READ FILE-IN INTO IN-RECORD
AT END
EXIT PERFORM
END-READ
IF IN-AMOUNT > 500
MOVE IN-RECORD TO SORT-RECORD
RELEASE SORT-RECORD
ADD 1 TO WS-RECORD-COUNT
END-IF
END-PERFORM.
CLOSE FILE-IN.
DISPLAY "SORT-INPUT-PROC: Released " WS-RECORD-COUNT " records"
.
*> --- Test 7: OUTPUT PROCEDURE (SR-N008) ---
SORT-OUTPUT-PROC.
SORT SORT-WORK ON ASCENDING KEY SORT-KEY
USING "INPUT.DAT"
OUTPUT PROCEDURE IS OP-SUMMARIZE.
IF RETURN-CODE = 0
DISPLAY "SORT-OUTPUT-PROC: PASS (summary applied)"
ELSE
DISPLAY "SORT-OUTPUT-PROC: FAIL RC=" RETURN-CODE
END-IF
.
OP-SUMMARIZE SECTION.
OPEN OUTPUT FILE-OUT.
MOVE 0 TO WS-RECORD-COUNT.
PERFORM UNTIL 1 = 2
RETURN SORT-WORK INTO SORT-RECORD
AT END
EXIT PERFORM
END-RETURN
MOVE SORT-KEY TO OUT-KEY
MOVE SORT-NAME TO OUT-NAME
MOVE SORT-AMOUNT TO OUT-AMOUNT
WRITE OUT-RECORD
ADD 1 TO WS-RECORD-COUNT
END-PERFORM.
CLOSE FILE-OUT.
DISPLAY "SORT-OUTPUT-PROC: Wrote " WS-RECORD-COUNT " records"
.
END PROGRAM SORT-PROGRAM.
+30
View File
@@ -0,0 +1,30 @@
20260622 232501 I 1000-INIT: Initialization complete
20260622 232501 I 1000-INIT: Initialization complete
20260622 232501 I 1000-INIT: Initialization complete
20260622 232501 I 3100-VALIDATE: CDR validation complete
20260622 232501 I 1000-INIT: Initialization complete
20260622 232501 I 3200-CALCULATE: Field enrichment complete
20260622 232501 W Duplicate key: CDR1000003ichment complete
20260622 232501 I 4000-REPORT: Multi-level keybreak complete
20260622 232501 I SR-N013: Multi-level keybreak report generated
20260622 232501 I 1000-INIT: Initialization complete
20260622 232501 W 3100-VALIDATE: Zero duration filtered
20260622 232501 W 3100-VALIDATE: Zero duration filtered
20260622 232501 W 3100-VALIDATE: Zero duration filtered
20260622 232501 W 3100-VALIDATE: Zero duration filtered
20260622 232501 W 3100-VALIDATE: Zero duration filtered
20260622 232501 I 3100-VALIDATE: CDR validation complete
20260622 232501 I 4000-REPORT: Multi-level keybreak complete
20260622 232501 W SR-N014: Duplicate keys detected and counted
20260622 232501 I 1000-INIT: Initialization complete
20260622 232501 I 3100-VALIDATE: CDR validation complete
20260622 232501 W Duplicate key: CDR1000004tion complete
20260622 232501 W Duplicate key: CDR1000006tion complete
20260622 232501 W Duplicate key: CDR1000003tion complete
20260622 232501 W Duplicate key: CDR1000008tion complete
20260622 232501 W Duplicate key: CDR1000002tion complete
20260622 232501 W Duplicate key: CDR1000001tion complete
20260622 232501 W Duplicate key: CDR1000007tion complete
20260622 232501 W Duplicate key: CDR2000002tion complete
20260622 232501 W Duplicate key: CDR2000001tion complete
20260622 232501 I 4000-REPORT: Multi-level keybreak complete
+10
View File
@@ -0,0 +1,10 @@
CDR1000001186139000138001PST0000060
CDR1000002186139000138001PST0000120
CDR1000003186139000138001PRM0003000
CDR1000004186138000139001PRM0000500
CDR1000005186138000139001ECO0001000
CDR1000006186138000139001PST0000350
CDR1000007186140000138001PST0000450
CDR1000008186139000139001PRM0002000
CDR2000001186141000138001ECO0015000
CDR2000002186141000138001ECO0025000
@@ -0,0 +1,9 @@
CDRC00000213300133001 00250
CDRC00000113700137001 00200
CDRB00000313200132001 00350
CDRB00000213500135001 00400
CDRB00000113800138001 00100
CDRA00000413100131001 00200
CDRA00000313400134001 00150
CDRA00000213600136001 00300
CDRA00000113900139001 00500
@@ -0,0 +1,86 @@
TELECOM SORT REPORT - RUN AT 20260622 232501
================================================================================
CDR1000006 18613800013 ECON MO 20260601 000000350============================
CDR1000004 18613800013 ECON MO 20260604 000000500============================
CDR1000005 18613800013 ECON MO 20260607 000001000============================
CALL TYPE: MO MOBILE-ORIG COUNT: 3 DURATIO
PLAN: ECON COUNT: 3 DURATION: 1850
CALL TYPE: MO MOBILE-ORIG COUNT: 3 DURATIO
PLAN: ECON COUNT: 3 DURATION: 1850
CUSTOMER: 18613800013 COUNT: 3 DURATION: 18
CDR1000002 18613900013 ECON MO 20260602 000000120 3 DURATION: 18
CDR1000001 18613900013 ECON MO 20260605 000000060 3 DURATION: 18
CDR1000003 18613900013 ECON MO 20260605 000003000 3 DURATION: 18
CDR1000008 18613900013 ECON MO 20260606 000002000 3 DURATION: 18
CALL TYPE: MO MOBILE-ORIG COUNT: 4 DURATIO
PLAN: ECON COUNT: 4 DURATION: 5180
CALL TYPE: MO MOBILE-ORIG COUNT: 4 DURATIO
PLAN: ECON COUNT: 4 DURATION: 5180
CUSTOMER: 18613900013 COUNT: 4 DURATION: 51
CDR1000007 18614000013 ECON MO 20260603 000000450 4 DURATION: 51
CALL TYPE: MO MOBILE-ORIG COUNT: 1 DURATIO
PLAN: ECON COUNT: 1 DURATION: 450
CALL TYPE: MO MOBILE-ORIG COUNT: 1 DURATIO
PLAN: ECON COUNT: 1 DURATION: 450
CUSTOMER: 18614000013 COUNT: 1 DURATION: 4
CDR2000002 18614100013 ECON MO 20260604 000025000 1 DURATION: 4
CDR2000001 18614100013 ECON MO 20260607 000015000 1 DURATION: 4
CALL TYPE: MO MOBILE-ORIG COUNT: 2 DURATIO
PLAN: ECON COUNT: 2 DURATION: 40000
CUSTOMER: 18614100013 COUNT: 2 DURATION: 400
GRAND TOTAL RECORDS: 10 TOTAL DURATION: 47480
CALL TYPE: MO MOBILE-ORIG COUNT: 2 DURATIO
PLAN: ECON COUNT: 2 DURATION: 40000
CUSTOMER: 18614100013 COUNT: 2 DURATION: 400
CALL TYPE: MO MOBILE-ORIG COUNT: 2 DURATIO
PLAN: ECON COUNT: 2 DURATION: 40000
CALL TYPE: MO MOBILE-ORIG COUNT: 2 DURATIO
TELECOM SORT REPORT - RUN AT 20260622 232501
================================================================================
CALL TYPE: MO MOBILE-ORIG COUNT: 2 DURATIO
PLAN: ECON COUNT: 2 DURATION: 40000
CUSTOMER: 18614100013 COUNT: 2 DURATION: 400
GRAND TOTAL RECORDS: 0 TOTAL DURATION: 0
CALL TYPE: MO MOBILE-ORIG COUNT: 2 DURATIO
PLAN: ECON COUNT: 2 DURATION: 40000
CUSTOMER: 18614100013 COUNT: 2 DURATION: 400
CALL TYPE: MO MOBILE-ORIG COUNT: 2 DURATIO
PLAN: ECON COUNT: 2 DURATION: 40000
CALL TYPE: MO MOBILE-ORIG COUNT: 2 DURATIO
TELECOM SORT REPORT - RUN AT 20260622 232501
================================================================================
CDR1000005 18613800013 ECON OT 20260601 000001000============================
CDR1000004 18613800013 ECON OT 20260601 000000500============================
CDR1000006 18613800013 ECON OT 20260601 000000350============================
CALL TYPE: OT OTHER COUNT: 3 DURATIO
PLAN: ECON COUNT: 3 DURATION: 1850
CALL TYPE: OT OTHER COUNT: 3 DURATIO
PLAN: ECON COUNT: 3 DURATION: 1850
CUSTOMER: 18613800013 COUNT: 3 DURATION: 18
CDR1000003 18613900013 ECON OT 20260601 000003000 3 DURATION: 18
CDR1000008 18613900013 ECON OT 20260601 000002000 3 DURATION: 18
CDR1000002 18613900013 ECON OT 20260601 000000120 3 DURATION: 18
CDR1000001 18613900013 ECON OT 20260601 000000060 3 DURATION: 18
CALL TYPE: OT OTHER COUNT: 4 DURATIO
PLAN: ECON COUNT: 4 DURATION: 5180
CALL TYPE: OT OTHER COUNT: 4 DURATIO
PLAN: ECON COUNT: 4 DURATION: 5180
CUSTOMER: 18613900013 COUNT: 4 DURATION: 51
CDR1000007 18614000013 ECON OT 20260601 000000450 4 DURATION: 51
CALL TYPE: OT OTHER COUNT: 1 DURATIO
PLAN: ECON COUNT: 1 DURATION: 450
CALL TYPE: OT OTHER COUNT: 1 DURATIO
PLAN: ECON COUNT: 1 DURATION: 450
CUSTOMER: 18614000013 COUNT: 1 DURATION: 4
CDR2000002 18614100013 ECON OT 20260601 000025000 1 DURATION: 4
CDR2000001 18614100013 ECON OT 20260601 000015000 1 DURATION: 4
CALL TYPE: OT OTHER COUNT: 2 DURATIO
PLAN: ECON COUNT: 2 DURATION: 40000
CUSTOMER: 18614100013 COUNT: 2 DURATION: 400
GRAND TOTAL RECORDS: 10 TOTAL DURATION: 47480
CALL TYPE: OT OTHER COUNT: 2 DURATIO
PLAN: ECON COUNT: 2 DURATION: 40000
CUSTOMER: 18614100013 COUNT: 2 DURATION: 400
CALL TYPE: OT OTHER COUNT: 2 DURATIO
PLAN: ECON COUNT: 2 DURATION: 40000
CALL TYPE: OT OTHER COUNT: 2 DURATIO
+15
View File
@@ -0,0 +1,15 @@
=== SORT STATISTICS ===
Input records = 000000005
Sorted records = 000000000
Filtered records = 000000000
Duplicate records = 000000000
Invalid records = 000000005
Hash total (dur) = 000000000000000
=== SORT STATISTICS ===
Input records = 000000010
Sorted records = 000000010
Filtered records = 000000000
Duplicate records = 000000009
Invalid records = 000000000
Hash total (dur) = 000000000047480
Hash total verified: 000000000047480
@@ -0,0 +1,10 @@
Group key: CDRA000001 Count: 1 Total: 50000
Group key: CDRA000002 Count: 1 Total: 30000
Group key: CDRA000003 Count: 1 Total: 15000
Group key: CDRA000004 Count: 1 Total: 20000
Group key: CDRB000001 Count: 1 Total: 10000
Group key: CDRB000002 Count: 1 Total: 40000
Group key: CDRB000003 Count: 1 Total: 35000
Group key: CDRC000001 Count: 1 Total: 20000
Group key: CDRC000002 Count: 1 Total: 25000
Group key: CDRC000002 Count: 1 Total: 25000