Sort and Merge
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
This page is written against ISO/IEC 1989:2023 (edition 3, January 2023; an upcoming 4th edition is in ballot), in which SORT and MERGE come from COBOL 74 and 85 and the table SORT from COBOL 2002; against IBM Enterprise COBOL for z/OS 6.5 (PTFs through September 2026) on z/OS 3.2, where the statements hand the work to DFSORT or an equivalent product; and against GnuCOBOL 3.2 (28 July 2023, the latest release), which has its own built-in sort, and with which every program on it was compiled with cobc -x -Wall and run on 2026-10-20 (and again with -std=ibm, which printed the same results unless the text says otherwise). z/OS examples are labelled "z/OS; not run here" and are checked against the Language Reference and the Programming Guide.
Sorting puts records in the order of one or more keys, and merging combines files that are already in that order. Batch systems do both constantly: the nightly Circulation run sorts the day’s loan transactions by book before the balance-line update of Sequential Files, and merges the transactions of several branches into one stream. This page covers the SD entry, the SORT statement in its three forms (file with USING/GIVING, file with procedures, and table), RELEASE and RETURN, MERGE, the special registers, the z/OS side with FASTSRT, DFSORT control statements and ICETOOL, and the mistakes that sort programs invite. The file statements around it are on File Concepts, SELECT and FD; sorting an in-memory table with SORT table and searching it are on Searching and Sorting Tables; the status codes of the files involved are on File Status Codes.
Where the book is outdated: Taulli’s Modern Mainframe Development (2022, chapter 3) shows sorting only as a DFSORT job in JCL, which is a valid and common approach and is described below. It does not cover the COBOL SORT and MERGE statements at all (no SD, no INPUT PROCEDURE, no RELEASE or RETURN), and neither does chapter 5, so everything about the statements comes from the official manuals. The book’s z/OS 2.4 context is also old; DFSORT is part of z/OS 3.2 with the same control-statement language.
The model: a sort file that is not a file
A sort works on a sort file that the program never opens. The program describes it with an SD (sort description) entry and a SELECT entry, names it in SORT, and the run time provides the work space.
SELECT sort-file ASSIGN TO assignment-name.
SD sort-file.
01 sort-record.
05 key-field ...
-
The
SELECTentry has noORGANIZATIONorACCESSclause. The file forms ofSORTandMERGEneed both theSELECTand theSD; the table form needs no file. -
The
SDentry has noBLOCK CONTAINS,LABELorFILE STATUS. Its record description defines the fields that can be keys. Using anFDinstead of anSDis a compile-time error. -
On z/OS the work data sets are described by the DFSORT job-step
DDstatements, for exampleSORTWK01; modern DFSORT allocates work space dynamically, so the JCL usually needs none. -
In GnuCOBOL the assignment name is a label and the sort uses temporary files governed by
COB_SORT_MEMORYandCOB_SORT_CHUNK; no JCL is involved.
The next sections cover the SORT forms in order of increasing control. The diagram shows the flow with procedures, the most general form: records enter the sort one by one through RELEASE in the input procedure, the sort orders them using work files, and the output procedure takes them back one by one with RETURN. USING replaces the input procedure with "read all records of these files", and GIVING replaces the output procedure with "write all records to these files".
SORT with USING and GIVING
The simplest form reads every record of the input files, sorts, and writes the result to the output files:
SORT sort-file
{ON {ASCENDING | DESCENDING} KEY key-name ...} ...
[WITH DUPLICATES IN ORDER]
[COLLATING SEQUENCE IS alphabet-name]
USING input-file-1 [input-file-2 ...]
GIVING output-file-1 [output-file-2 ...]
-
Keys. Each
KEYnames a field of the sort record. They are listed from the most to the least significant, whatever the grouping ofASCENDINGandDESCENDING; a keyword applies to all following keys until the next one. A key cannot have anOCCURSclause or be under one, and with variable-length records all keys must lie within the shortest record. -
Same position in every input. The key must be at the same position and in the same format in the sort record and in every input record.
-
WITH DUPLICATES IN ORDER. Records with equal keys come out in the order of the input files in theUSINGlist and within a file in their input order (or release order, with an input procedure). Without it the order of equal keys is undefined. The balance-line update depends on this: a checkout and a return of the same book must stay in the order in which they happened. -
COLLATING SEQUENCE. It applies to alphabetic and alphanumeric keys only, and names an alphabet fromSPECIAL-NAMES. Without it, the program collating sequence applies; if none is set, Enterprise COBOL uses EBCDIC, and GnuCOBOL the native ASCII. -
USINGandGIVINGfiles are described byFDentries, must be closed when theSORTruns, and are opened, read or written and closed by the run time. The records of aGIVINGfile are written like a plainWRITE.
The next program sorts the day’s loan transactions by book number and, within a book, by date, keeping the arrival order of equal keys. The SD record is the LOANREC copybook with its prefix renamed to SRT- using COPY ... REPLACING LEADING, so that the keys have their own names.
IDENTIFICATION DIVISION.
PROGRAM-ID. LOANSORT.
* SORT ... USING ... GIVING: order the loans by book, then date.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT LOAN-IN ASSIGN TO "LOANTRAN"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT LOAN-OUT ASSIGN TO "LOANSRT"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT SORT-FILE ASSIGN TO "SORTWK01".
DATA DIVISION.
FILE SECTION.
FD LOAN-IN.
01 LOAN-IN-LINE PIC X(30).
FD LOAN-OUT.
01 LOAN-OUT-LINE PIC X(30).
SD SORT-FILE.
COPY LOANREC REPLACING LEADING ==LOAN-== BY ==SRT-==.
PROCEDURE DIVISION.
0000-MAIN-LINE.
SORT SORT-FILE
ON ASCENDING KEY SRT-BOOK-ID
ON ASCENDING KEY SRT-DATE
WITH DUPLICATES IN ORDER
USING LOAN-IN
GIVING LOAN-OUT
DISPLAY "SORT-RETURN = " SORT-RETURN
STOP RUN.
Compiled with cobc -x -Wall -I. loansort.cob (and with -std=ibm), no warnings, it prints:
SORT-RETURN = +000000000
and LOANSRT holds the four transactions in book order (the sorted file that the balance-line update reads):
O00010000000120261020
R00010000000120261020
O00010100000220261020
O00010200000320261020
The two transactions of book 1 kept their arrival order. SORT-RETURN is a special register that holds 0 after a successful sort; GnuCOBOL shows it as a signed number. The key names are checked at compile time: a key that is not in the sort record is reported by cobc, and an FD used where an SD is required is rejected.
bad1.cob:17: error: 'SRT-NOKEY' is not defined
bad1.cob:8: error: must be an SD filename
INPUT PROCEDURE and OUTPUT PROCEDURE
A procedure replaces the automatic read or write when the program has to do something to each record: drop or fix records before sorting, build a record from several sources, or print directly from the sorted stream.
SORT sort-file ON ASCENDING KEY key-name ...
INPUT PROCEDURE IS section-or-paragraph [THRU end-name]
OUTPUT PROCEDURE IS section-or-paragraph [THRU end-name]
-
The input procedure reads from any file it likes, and passes each record to the sort with
RELEASE sort-record [FROM identifier]. It may release zero records, one per input record, or many. It must not execute aSORT, aMERGEor aRETURN. -
The output procedure takes the sorted records one by one with
RETURN sort-file [INTO identifier] AT END ... [NOT AT END ...] END-RETURN.AT ENDis required in the statement and runs when there are no more records. It must not execute aSORT, aMERGEor aRELEASE. -
Control leaves the input procedure through the end of its last paragraph or section, and the sort starts. The sort ends when the output procedure runs off its end, and the program continues after the
SORT. Do notSTOP RUNorGO TOout of the range. -
RELEASEandRETURNname the record of the sort file, asWRITEnames a record;FROMandINTOdo the moves. -
The range is the section or the
THRUrange, executed from the first statement to the last. Everything physically inside it runs, as the next example shows.
The following program takes the transactions of the next day in LOANDAY, which contains two bad records: type X and a non-numeric book number. The input procedure releases only valid records (O or R with numeric ids); the output procedure shows them in book order and, within a book, newest date first.
IDENTIFICATION DIVISION.
PROGRAM-ID. LOANPROC.
* SORT with INPUT PROCEDURE (validate, RELEASE) and OUTPUT
* PROCEDURE (RETURN, count transactions per book).
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT LOAN-IN ASSIGN TO "LOANDAY"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT SORT-FILE ASSIGN TO "SORTWK01".
DATA DIVISION.
FILE SECTION.
FD LOAN-IN.
01 LOAN-IN-LINE PIC X(30).
SD SORT-FILE.
COPY LOANREC REPLACING LEADING ==LOAN-== BY ==SRT-==.
WORKING-STORAGE SECTION.
COPY LOANREC.
01 WS-EOF-IN PIC X VALUE "N".
88 END-OF-INPUT VALUE "Y".
01 WS-EOF-SORT PIC X VALUE "N".
88 END-OF-SORTED VALUE "Y".
01 WS-RELEASED PIC 9(3) VALUE ZERO.
01 WS-REJECTED PIC 9(3) VALUE ZERO.
01 WS-PREV-BOOK PIC 9(6) VALUE ZERO.
01 WS-BOOK-COUNT PIC 9(3) VALUE ZERO.
PROCEDURE DIVISION.
0000-MAIN-LINE.
SORT SORT-FILE
ON ASCENDING KEY SRT-BOOK-ID
ON DESCENDING KEY SRT-DATE
WITH DUPLICATES IN ORDER
INPUT PROCEDURE IS 1000-SELECT-LOANS
OUTPUT PROCEDURE IS 2000-REPORT-LOANS
DISPLAY "released " WS-RELEASED ", rejected " WS-REJECTED
", SORT-RETURN " SORT-RETURN
STOP RUN.
1000-SELECT-LOANS SECTION.
1000-START.
OPEN INPUT LOAN-IN
PERFORM UNTIL END-OF-INPUT
READ LOAN-IN INTO LOAN-RECORD
AT END SET END-OF-INPUT TO TRUE
NOT AT END PERFORM 1100-VALIDATE
END-READ
END-PERFORM
CLOSE LOAN-IN.
1000-EXIT.
EXIT.
1100-VALIDATE SECTION.
IF (LOAN-CHECKOUT OR LOAN-RETURN)
AND LOAN-MEMBER-ID IS NUMERIC
AND LOAN-BOOK-ID IS NUMERIC
RELEASE SRT-RECORD FROM LOAN-RECORD
ADD 1 TO WS-RELEASED
ELSE
DISPLAY "rejected: " LOAN-RECORD(1:21)
ADD 1 TO WS-REJECTED
END-IF.
2000-REPORT-LOANS SECTION.
2000-START.
PERFORM UNTIL END-OF-SORTED
RETURN SORT-FILE
AT END SET END-OF-SORTED TO TRUE
NOT AT END PERFORM 2100-SHOW-LOAN
END-RETURN
END-PERFORM.
2000-EXIT.
EXIT.
2100-SHOW-LOAN SECTION.
DISPLAY "book " SRT-BOOK-ID " " SRT-DATE " " SRT-TYPE
" member " SRT-MEMBER-ID.
Compiled with cobc -x -Wall -I. loanproc.cob (and with -std=ibm), no warnings, it prints:
rejected: X00010000000120261021
rejected: O0001AB00000320261021
book 000002 20261021 O member 000101
book 000002 20261020 O member 000101
book 000003 20261021 R member 000102
book 000004 20261021 O member 000100
released 004, rejected 002, SORT-RETURN +000000000
The two rejects were reported while the input was read, and four of the six records reached the sort. Book 2 appears twice with the later date first, as the DESCENDING KEY SRT-DATE asks. The COPY LOANREC in WORKING-STORAGE supplies the validation record with the LOAN- names (with the 88-level condition names), and the SD has a second copy with the SRT- names; RELEASE ... FROM copies one into the other.
Falling out of the procedure range
The procedures above are sections, and the helper paragraphs 1100-VALIDATE and 2100-SHOW-LOAN are sections too. If instead they were paragraphs placed below the procedure’s EXIT, they would belong to the same section and would run once more after the loop. This is the same program with the helpers as paragraphs; everything else is identical:
1000-SELECT-LOANS SECTION.
1000-START.
...
1000-EXIT.
EXIT.
1100-VALIDATE.
IF (LOAN-CHECKOUT OR LOAN-RETURN) ...
The compiler gives no warning. The input procedure ends at the next section header, so 1100-VALIDATE runs after the loop with the record that is still in LOAN-RECORD, and the output procedure does the same with 2100-SHOW-LOAN:
rejected: X00010000000120261021
rejected: O0001AB00000320261021
rejected: O0001AB00000320261021
book 000002 20261021 O member 000101
book 000002 20261020 O member 000101
book 000003 20261021 R member 000102
book 000004 20261021 O member 000100
book 000004 20261021 O member 000100
released 004, rejected 003, SORT-RETURN +000000000
The last record of the input was rejected twice (three rejects instead of two), and the last sorted record was shown twice (book 4 appears twice). The count released 004 is correct because the extra execution of the validation found a bad record. Keep the helpers outside the range: make each one a section of its own, as the correct program does, put them before the procedure, or use THRU with an explicit end paragraph. This applies to every procedure range: PERFORM section and the INPUT PROCEDURE range both run to the end of the section.
COLLATING SEQUENCE
The default order of an alphanumeric key follows the character set: EBCDIC on z/OS, ASCII on most other systems. So with ASCII all capital letters sort before all lower-case ones. A COLLATING SEQUENCE clause names an alphabet defined in SPECIAL-NAMES: STANDARD-1 (ASCII), STANDARD-2 (ISO 646), NATIVE (the machine’s own), EBCDIC, or one built from literals. The program below defines an alphabet in which each letter and its lower-case form have the same position (ALSO), and sorts four names with it:
IDENTIFICATION DIVISION.
PROGRAM-ID. COLL.
* Sort names with an alphabet that ignores case.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
ALPHABET NOCASE IS
"A" ALSO "a", "B" ALSO "b", "C" ALSO "c",
"D" ALSO "d", "E" ALSO "e", "F" ALSO "f".
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SORT-FILE ASSIGN TO "SORTWK01".
DATA DIVISION.
FILE SECTION.
SD SORT-FILE.
01 SORT-REC PIC X(8).
WORKING-STORAGE SECTION.
01 WS-EOF PIC X VALUE "N".
88 END-OF-SORT VALUE "Y".
PROCEDURE DIVISION.
0000-MAIN-LINE.
SORT SORT-FILE ON ASCENDING KEY SORT-REC
COLLATING SEQUENCE IS NOCASE
INPUT PROCEDURE IS 1000-LOAD
OUTPUT PROCEDURE IS 2000-SHOW
STOP RUN.
1000-LOAD SECTION.
MOVE "beta" TO SORT-REC RELEASE SORT-REC
MOVE "Alpha" TO SORT-REC RELEASE SORT-REC
MOVE "delta" TO SORT-REC RELEASE SORT-REC
MOVE "Charlie" TO SORT-REC RELEASE SORT-REC.
2000-SHOW SECTION.
PERFORM UNTIL END-OF-SORT
RETURN SORT-FILE
AT END SET END-OF-SORT TO TRUE
NOT AT END DISPLAY SORT-REC
END-RETURN
END-PERFORM.
Compiled with cobc -x -Wall -I. coll.cob (and with -std=ibm), no warnings, it prints the names in alphabetical order regardless of case:
Alpha
beta
Charlie
delta
With the default ASCII order the result would be Alpha, Charlie, beta, delta. The clause affects alphabetic and alphanumeric keys only; numeric keys are compared by value. Accented characters and locale-dependent order need the locale features described on National, UTF-8 and Code Pages.
MERGE
MERGE combines two or more files that are already in the key order:
MERGE merge-file
{ON {ASCENDING | DESCENDING} KEY key-name ...} ...
[COLLATING SEQUENCE IS alphabet-name]
USING input-file-1 input-file-2 [input-file-3 ...]
{GIVING output-file ... |
OUTPUT PROCEDURE IS section-or-paragraph [THRU end-name]}
-
There is no input procedure: the inputs are read as they are. At least two
USINGfiles are needed. -
The records of each input file must already be in the key order of the
MERGE; the statement does not check it. Out-of-order input gives out-of-order output. -
With equal keys, the records of the first
USINGfile come first, then those of the second, and so on.WITH DUPLICATES IN ORDERis the behaviour ofMERGE, so the clause is not needed. -
MERGEuses anSD, likeSORT.
Two branches send their sorted loans of the day, LOANA (books 1 and 3) and LOANB (books 2, 3 and 4). The merge writes one file in book order:
IDENTIFICATION DIVISION.
PROGRAM-ID. LOANMERGE.
* MERGE two branch files that are already in book order.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT BRANCH-A ASSIGN TO "LOANA"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT BRANCH-B ASSIGN TO "LOANB"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT LOAN-ALL ASSIGN TO "LOANALL"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT MERGE-FILE ASSIGN TO "MERGEWK".
DATA DIVISION.
FILE SECTION.
FD BRANCH-A.
01 BRANCH-A-LINE PIC X(30).
FD BRANCH-B.
01 BRANCH-B-LINE PIC X(30).
FD LOAN-ALL.
01 LOAN-ALL-LINE PIC X(30).
SD MERGE-FILE.
COPY LOANREC REPLACING LEADING ==LOAN-== BY ==MRG-==.
PROCEDURE DIVISION.
0000-MAIN-LINE.
MERGE MERGE-FILE
ON ASCENDING KEY MRG-BOOK-ID
USING BRANCH-A BRANCH-B
GIVING LOAN-ALL
DISPLAY "SORT-RETURN = " SORT-RETURN
STOP RUN.
Compiled with cobc -x -Wall -I. loanmerge.cob (and with -std=ibm), no warnings, it prints SORT-RETURN = +000000000 and writes LOANALL:
O00010000000120261020
O00010100000220261020
O00010200000320261020
R00010200000320261021
O00010000000420261020
The two records of book 3 are in file order: the checkout from branch A first, then the return from branch B. Merging is linear (each input is read once) and needs no work files beyond the buffers, so it is much cheaper than a sort of the concatenated files, which is why a nightly job sorts each branch in parallel and merges the results.
SORT-RETURN and other special registers
-
SORT-RETURNholds the completion code of the lastSORTorMERGE:0for success and16for failure. Moving16to it in an input or output procedure stops the sort. The register is a binary signed number; GnuCOBOL displays it as+000000000. -
A failure does not abend by itself. Test the register after every
SORTandMERGE. -
On z/OS,
SORT-CONTROLnames the DD that holds DFSORT control statements (defaultIGZSRTCD), andSORT-CORE-SIZE,SORT-FILE-SIZE,SORT-MESSAGEandSORT-MODE-SIZEcorrespond to keywords of that control data set. They are set before theSORT. GnuCOBOL hasSORT-RETURNand ignores the others.
A real failure on GnuCOBOL 3.2.0: the USING file was left open by the program (OPEN INPUT LOAN-IN before the SORT). The sort cannot open it, SORT-RETURN is 16, and the output file is not produced:
SORT-RETURN = +000000016
status 00
libcob: warning: implicit CLOSE of LOAN-IN ('LOANTRAN')
The status 00 is the status of the program’s own earlier OPEN, not of the sort. The USING and GIVING files must be closed when the SORT starts.
Sorting a table
COBOL 2002 added a third form that sorts a table in storage, with no file at all:
SORT table-name ON {ASCENDING | DESCENDING} KEY key-name ...
[WITH DUPLICATES IN ORDER]
[COLLATING SEQUENCE IS alphabet-name]
The table must have an OCCURS clause. The keys must be the table item or a field inside it, and the sorted elements go back to the same table. Enterprise COBOL supports it (even with the THREAD option, unlike the file form), GnuCOBOL supports it too, and it is covered with examples on Searching and Sorting Tables.
Sorting on z/OS: DFSORT, FASTSRT and the restrictions
In Enterprise COBOL the SORT and MERGE statements call DFSORT (or an equivalent such as SyncSort), which must be available at run time. Several points are specific to that engine:
-
FASTSRT. With theFASTSRTcompiler option, DFSORT itself performs the I/O on theUSINGandGIVINGfiles instead of Enterprise COBOL, which is faster for most sorts. The files must meet the conditions for it that the Programming Guide lists. WithoutFASTSRTthe sort does not check for errors on opening, closing and I/O of those files, so the program should testSORT-RETURN. -
No
SORTunder z/OS UNIX. A program containingSORTorMERGEcannot run under z/OS UNIX, including through BPXBATCH, cannot be compiled withTHREAD(the table form can), and cannot directly or indirectly call code that needs z/OS UNIX services or threads, such as a JVM. -
The conventional technique is not supported: with
NOBLKSET, with tape for intermediate storage, or withL5in the DFSORTRECORDoption. -
Work space. DFSORT allocates work data sets dynamically in current installations. Sort work
DDstatements in the JCL (SORTWKnn) are still honoured. -
In an output procedure the sorted records come only through
RETURN; aREADof the sort file is not allowed.
DFSORT and ICETOOL as an alternative to a COBOL sort
Sorting a file does not need a COBOL program. DFSORT is a utility that a job step runs directly with control statements; for plain ordering, selecting and reformatting it beats a program in length and nearly always in speed. The Circulation job can sort the transactions and keep only checkouts and returns in one step (z/OS; not run here):
//SORTSTEP EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD DISP=SHR,DSN=USERID.CIRC.LOANTRAN
//SORTOUT DD DSN=USERID.CIRC.LOANSRT,DISP=(NEW,CATLG,DELETE),
// RECFM=FB,LRECL=30,SPACE=(TRK,(5,1))
//SYSIN DD *
SORT FIELDS=(8,6,ZD,A,14,8,ZD,A),EQUALS
INCLUDE COND=(1,1,CH,EQ,C'O',OR,1,1,CH,EQ,C'R')
/*
-
SORT FIELDS=(8,6,ZD,A,14,8,ZD,A)sorts on the six-digit zoned decimal at position 8 (the book number inLOANREC) and then on the eight digits at position 14 (the date), both ascending. Positions are bytes from 1, as in the copybook (LOAN-TYPEat 1, member at 2, book at 8, date at 14). -
EQUALSkeeps records with equal keys in their input order, the counterpart ofWITH DUPLICATES IN ORDER. -
INCLUDE COND=...drops every record whose type is neitherOnorR;OMITdoes the opposite.OUTREC FIELDS=(...)orOUTFILcan reformat or split the output, andSUM FIELDS=NONEremoves duplicates.
ICETOOL is the front end for DFSORT that runs several operations in one step, each one reading and writing named DDs. This step sorts with the same control statements, and counts the records of the input (z/OS; not run here):
//TOOLRUN EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//IN DD DISP=SHR,DSN=USERID.CIRC.LOANTRAN
//OUT DD DSN=USERID.CIRC.LOANSRT,DISP=(NEW,CATLG,DELETE),
// RECFM=FB,LRECL=30,SPACE=(TRK,(5,1))
//CTL1CNTL DD *
SORT FIELDS=(8,6,ZD,A,14,8,ZD,A),EQUALS
/*
//TOOLIN DD *
COUNT FROM(IN)
SORT FROM(IN) TO(OUT) USING(CTL1)
/*
The choice between a COBOL sort and DFSORT:
COBOL SORT |
DFSORT or ICETOOL step | |
|---|---|---|
Best for |
Validation or reformatting that needs program logic in the input or output procedure; sorting inside a program that goes on to use the result |
Plain order, filter, reformat, merge, join, count and report steps between programs |
Cost |
A program to write, compile and maintain |
A few control statements in the JCL |
Failure handling |
|
The step return code ( |
Portability |
Runs, with different sort engines, on z/OS and with GnuCOBOL |
z/OS only (equivalents are |
On the PC the counterpart of the first step is the shell command used on the sequential files page (sort -s -k1.8,1.13 LOANTRAN > LOANSRT), where -s is the stable sort that keeps equal keys in input order.
GnuCOBOL’s built-in sort
GnuCOBOL does not call an external sort program. SORT and MERGE run inside the run-time library, with the records in memory and in temporary files. Settings are environment variables or entries in the run-time configuration:
-
COB_SORT_MEMORYis the memory used before it spills to disk, andCOB_SORT_CHUNKthe chunk size of the temporary files (see the run-time configuration chapter of the manual for the defaults and units). -
SORT-RETURNis set as in the standard. The extra Enterprise COBOL special registers for DFSORT are not needed with the built-in sort and were not tested here. -
WITH DUPLICATES IN ORDERis honoured, as the examples above show; without it GnuCOBOL’s order of equal keys must not be relied on. -
Records with trailing spaces trimmed in
LINE SEQUENTIALfiles are padded when read, so a key defined at the end of a short line sees spaces.
Common mistakes
-
Opening the
USINGorGIVINGfile before theSORT. The sort cannot open it and fails withSORT-RETURN16; close it first. -
Unsorted input to
MERGE. The output is not sorted and no message is given. -
Leaving out
WITH DUPLICATES IN ORDER. Transactions with the same key come out in any order, which turns a checkout followed by a return into a return followed by a checkout. -
Helper paragraphs inside a procedure section. They run once more after the loop; make them sections or place them outside the range.
-
A key that moves with the record. A key under an
OCCURSentry, or at a different position in different input files, is invalid. -
Forgetting the case and collating sequence. ASCII and EBCDIC order differ (ASCII: digits, capitals, lower-case; EBCDIC: lower-case, capitals, digits), so a sorted file can change order when it moves between platforms.
-
Not testing
SORT-RETURN. A failed sort does not stop the program by itself. -
Sorting with a
SORTstatement in a z/OS UNIX orTHREADprogram. It is not supported; use a DFSORT job step or the table form. -
Writing a sort program for a plain reordering on z/OS. A DFSORT step with
SORT FIELDS=does it with no code.
References
-
Enterprise COBOL for z/OS 6.5 Language Reference: SORT statement
-
Enterprise COBOL for z/OS 6.5 Language Reference: MERGE statement
-
Enterprise COBOL for z/OS 6.5 Language Reference: ALPHABET clause
-
Enterprise COBOL for z/OS 6.5 Programming Guide: Sorting and merging files
-
Enterprise COBOL for z/OS 6.5 Programming Guide: Choosing alternate collating sequences
-
Tom Taulli, Modern Mainframe Development, O’Reilly Media, 2022 (chapter 3, consulted for the topics only)