SORT and MERGE

COBOL COBOL 2014 (ISO/IEC 1989:2014), built with GnuCOBOL 3.x Β· βœ“ verified by execution on 2026-08-16

Most languages rely on libraries or external tools to sort data. In COBOL, sorting and merging are first-class language features built directly into the compiler. The SORT and MERGE verbs allow you to reorder massive datasets without writing complex algorithms.

To use these verbs, you must define a Sort Description (SD) entry in your FILE SECTION. The SD acts as the blueprint for the internal workspace where the sort happens.

The Internal Sort Workspace

Think of the SD as a temporary holding area that only exists during the sort. Records enter the workspace, get rearranged, and are then passed back to your program or written directly to a file.

Input File USING SD Work File GIVING Output File INPUT PROCEDURE RELEASE OUTPUT PROCEDURE RETURN

Basic SORT using Files

The simplest way to sort is to take an input file, reorder its records based on a key, and write the result directly to an output file.

cobol βœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. SortBasic.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT IN-FILE ASSIGN TO "in.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT OUT-FILE ASSIGN TO "out.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT WORK-FILE ASSIGN TO "work1.tmp".
       DATA DIVISION.
       FILE SECTION.
       FD  IN-FILE.
       01  IN-REC PIC X(10).
       FD  OUT-FILE.
       01  OUT-REC PIC X(10).
       SD  WORK-FILE.
       01  WORK-REC.
           05 WORK-KEY PIC X(10).
       PROCEDURE DIVISION.
           SORT WORK-FILE
               ON ASCENDING KEY WORK-KEY
               USING IN-FILE
               GIVING OUT-FILE.
           STOP RUN.
Output
 

In this example, the SORT verb automatically opens IN-FILE, reads all its records into the WORK-FILE, sorts them ASCENDING by WORK-KEY, and writes the result to OUT-FILE before closing both files.

Bypassing Physical Files: INPUT PROCEDURE

You don’t need a physical input file to use SORT. You can intercept the beginning of the sort process using an INPUT PROCEDURE. Instead of reading from a file, your program dynamically generates or modifies records and hands them to the sort using the RELEASE statement.

cobol βœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. SortInput.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT OUT-FILE ASSIGN TO "out2.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT WORK-FILE ASSIGN TO "work2.tmp".
       DATA DIVISION.
       FILE SECTION.
       FD  OUT-FILE.
       01  OUT-REC PIC X(5).
       SD  WORK-FILE.
       01  WORK-REC.
           05 WORK-KEY PIC X(5).
       PROCEDURE DIVISION.
           SORT WORK-FILE
               ON ASCENDING KEY WORK-KEY
               INPUT PROCEDURE IS GEN-DATA
               GIVING OUT-FILE.
           STOP RUN.
       GEN-DATA SECTION.
           MOVE "Zebra" TO WORK-REC.
           RELEASE WORK-REC.
           MOVE "Apple" TO WORK-REC.
           RELEASE WORK-REC.
           EXIT.
Output
 

When SORT runs, it calls GEN-DATA SECTION like a subroutine. Once the procedure hits EXIT, the records are sorted and dumped into OUT-FILE.

Some learners mistakenly believe that an INPUT PROCEDURE is a completely external subprogram (like one called via CALL). In reality, it is just a section within the same program. Can you predict what this program outputs?

Predict the output cobol

Read the code. What exactly will it print? Commit to an answer before you look.

       ID DIVISION. PROGRAM-ID. P.
       ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION.
       FILE-CONTROL. SELECT W ASSIGN "w.tmp".
       DATA DIVISION. FILE SECTION. SD W. 01 R PIC X.
       WORKING-STORAGE SECTION. 01 C PIC 9 VALUE 0.
       PROCEDURE DIVISION.
           SORT W ON ASCENDING R
             INPUT PROCEDURE L OUTPUT PROCEDURE O.
           DISPLAY "COUNT=" C. STOP RUN.
       L SECTION.
           ADD 1 TO C. RELEASE R FROM "A".
           ADD 1 TO C. RELEASE R FROM "B".
           EXIT.
       O SECTION. EXIT.
Output
COUNT=2

Retrieving Records: OUTPUT PROCEDURE

Just as INPUT PROCEDURE feeds data in, an OUTPUT PROCEDURE pulls data out. Instead of writing directly to a file via GIVING, you can retrieve the sorted records one by one using the RETURN statement.

cobol βœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. SortOutput.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT IN-FILE ASSIGN TO "in2.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT WORK-FILE ASSIGN TO "work3.tmp".
       DATA DIVISION.
       FILE SECTION.
       FD  IN-FILE.
       01  IN-REC PIC X(5).
       SD  WORK-FILE.
       01  WORK-REC.
           05 WORK-KEY PIC X(5).
       WORKING-STORAGE SECTION.
       01  WS-EOF PIC X VALUE 'N'.
       PROCEDURE DIVISION.
       MAIN-SECTION SECTION.
       BUILD-INPUT.
      *> Create the input file first, so the example is self-contained.
           OPEN OUTPUT IN-FILE
           WRITE IN-REC FROM "Gamma"
           WRITE IN-REC FROM "Alpha"
           WRITE IN-REC FROM "Beta "
           CLOSE IN-FILE

           SORT WORK-FILE
               ON ASCENDING KEY WORK-KEY
               USING IN-FILE
               OUTPUT PROCEDURE IS DISP-DATA
           STOP RUN.

       DISP-DATA SECTION.
       READ-LOOP.
           RETURN WORK-FILE
               AT END MOVE 'Y' TO WS-EOF
               NOT AT END DISPLAY WORK-REC
           END-RETURN
           IF WS-EOF = 'N' GO TO READ-LOOP.
           EXIT.
Output
Alpha
Beta 
Gamma

Notice that RETURN works almost exactly like READ, using the AT END clause to detect when the sorted records run out.

Sorting In-Memory Tables

By combining INPUT PROCEDURE and OUTPUT PROCEDURE, you bypass physical files entirely. You RELEASE records from memory, and RETURN them back to memory.

cobol βœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. SortTable.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT WORK-FILE ASSIGN TO "work5.tmp".
       DATA DIVISION.
       FILE SECTION.
       SD  WORK-FILE.
       01  WORK-REC.
           05 WORK-KEY PIC 9(2).
       WORKING-STORAGE SECTION.
       01  WS-EOF PIC X VALUE 'N'.
       PROCEDURE DIVISION.
           SORT WORK-FILE
               ON ASCENDING KEY WORK-KEY
               INPUT PROCEDURE IS LOAD-DATA
               OUTPUT PROCEDURE IS READ-DATA.
           STOP RUN.
       LOAD-DATA SECTION.
           MOVE 42 TO WORK-KEY. RELEASE WORK-REC.
           MOVE 17 TO WORK-KEY. RELEASE WORK-REC.
           MOVE 99 TO WORK-KEY. RELEASE WORK-REC.
           EXIT.
       READ-DATA SECTION.
       READ-LOOP.
           RETURN WORK-FILE
               AT END MOVE 'Y' TO WS-EOF
               NOT AT END DISPLAY WORK-KEY
           END-RETURN
           IF WS-EOF = 'N' GO TO READ-LOOP.
           EXIT.
Output
17
42
99

The MERGE Statement

MERGE works similarly to SORT, but it combines two or more already sorted files. Because the files are already sequenced, MERGE simply zips them together. Note that MERGE accepts an OUTPUT PROCEDURE, but does not support an INPUT PROCEDURE.

cobol βœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. MergeBasic.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT IN-1 ASSIGN TO "m1.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT IN-2 ASSIGN TO "m2.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT OUT-FILE ASSIGN TO "m-out.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT WORK-FILE ASSIGN TO "work4.tmp".
       DATA DIVISION.
       FILE SECTION.
       FD  IN-1.
       01  IN1-REC PIC X(4).
       FD  IN-2.
       01  IN2-REC PIC X(4).
       FD  OUT-FILE.
       01  OUT-REC PIC X(4).
       SD  WORK-FILE.
       01  WORK-REC.
           05 WORK-KEY PIC X(4).
       PROCEDURE DIVISION.
           MERGE WORK-FILE
               ON ASCENDING KEY WORK-KEY
               USING IN-1, IN-2
               GIVING OUT-FILE.
           STOP RUN.
Output
 

If you want to view the merged results programmatically, use an OUTPUT PROCEDURE:

cobol βœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. MergeOut.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT IN-1 ASSIGN TO "m1.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT IN-2 ASSIGN TO "m2.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT WORK-FILE ASSIGN TO "work6.tmp".
       DATA DIVISION.
       FILE SECTION.
       FD  IN-1.
       01  IN1-REC PIC X(4).
       FD  IN-2.
       01  IN2-REC PIC X(4).
       SD  WORK-FILE.
       01  WORK-REC.
           05 WORK-KEY PIC X(4).
       WORKING-STORAGE SECTION.
       01  WS-EOF PIC X VALUE 'N'.
       PROCEDURE DIVISION.
       MAIN-SECTION SECTION.
       BUILD-INPUT.
      *> MERGE requires both inputs to ALREADY be sorted. Build them that way.
           OPEN OUTPUT IN-1
           WRITE IN1-REC FROM "1001"
           WRITE IN1-REC FROM "3003"
           CLOSE IN-1

           OPEN OUTPUT IN-2
           WRITE IN2-REC FROM "2002"
           WRITE IN2-REC FROM "4004"
           CLOSE IN-2

           MERGE WORK-FILE
               ON ASCENDING KEY WORK-KEY
               USING IN-1, IN-2
               OUTPUT PROCEDURE IS DISP-DATA
           STOP RUN.

       DISP-DATA SECTION.
       READ-LOOP.
           RETURN WORK-FILE
               AT END MOVE 'Y' TO WS-EOF
               NOT AT END DISPLAY WORK-KEY
           END-RETURN
           IF WS-EOF = 'N' GO TO READ-LOOP.
           EXIT.
Output
1001
2002
3003
4004

Edge Cases

Check yourself

Can you use the SORT statement without a physical input or output file?

Reveal answer

Yes, by using an INPUT PROCEDURE and OUTPUT PROCEDURE, you can sort entirely in memory. β€” By utilizing INPUT PROCEDURE and OUTPUT PROCEDURE, you can bypass physical files and sort entirely in-memory arrays and tables.

What happens if you use MERGE on files that are not already sorted?

Reveal answer

The resulting sequence will be incorrect. β€” MERGE expects all input files to already be sorted on the specified keys. If they aren't, it blindly merges them and produces corrupted output sequences.

How do you insert a record into the sort workspace inside an INPUT PROCEDURE?

Reveal answer

Use the RELEASE statement. β€” You must use the RELEASE statement to insert records into the sort workspace. WRITE is only for physical files.

Challenges

🐞 Bug Hunt +15 XP

This program intends to sort employee IDs in descending order, but the output is backwards. Fix the bug so the output displays 99, then 50, then 10.

This code runs. It just does the wrong thing. Read it, find the defect, fix it β€” the tests below decide when you are right.

cobol βœ“ solution verified at build time

COBOL has no in-browser runtime, so this one is pen-and-paper: work out what the fixed code should be, then open the solution and compare. The expected output below is real β€” it came from compiling the solution with GnuCOBOL when this page was built.

  • Test 1 β€” expects "99\n50\n10"
Need a hint? (βˆ’25% XP)

Check the SORT clause that determines the sort direction. It currently says ASCENDING.

Show solution (0 XP)
IDENTIFICATION DIVISION.
PROGRAM-ID. BugHuntSort.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT WORK-FILE ASSIGN TO "work7.tmp".
DATA DIVISION.
FILE SECTION.
SD  WORK-FILE.
01  WORK-REC.
    05 WORK-KEY PIC 9(2).
WORKING-STORAGE SECTION.
01  WS-EOF PIC X VALUE 'N'.
PROCEDURE DIVISION.
    SORT WORK-FILE
        ON DESCENDING KEY WORK-KEY
        INPUT PROCEDURE IS LOAD-DATA
        OUTPUT PROCEDURE IS READ-DATA.
    STOP RUN.
LOAD-DATA SECTION.
    MOVE 10 TO WORK-KEY. RELEASE WORK-REC.
    MOVE 99 TO WORK-KEY. RELEASE WORK-REC.
    MOVE 50 TO WORK-KEY. RELEASE WORK-REC.
    EXIT.
READ-DATA SECTION.
READ-LOOP.
    RETURN WORK-FILE
        AT END MOVE 'Y' TO WS-EOF
        NOT AT END DISPLAY WORK-KEY
    END-RETURN
    IF WS-EOF = 'N' GO TO READ-LOOP.
    EXIT.

Challenge 2 +20 XP

Write an INPUT PROCEDURE named `LOAD-DATA SECTION` that releases three names into the sort workspace: 'Charlie', 'Alice', and 'Bob'. The program structure is already set up to sort them and print them out.

cobol βœ“ solution verified at build time

COBOL has no in-browser runtime, so this one is pen-and-paper: work out what the fixed code should be, then open the solution and compare. The expected output below is real β€” it came from compiling the solution with GnuCOBOL when this page was built.

  • Test 1 β€” expects "Alice \nBob \nCharlie "
Need a hint? (βˆ’25% XP)

Move each name to WORK-NAME, then use RELEASE WORK-REC. Don't forget to put it inside LOAD-DATA SECTION. and end with EXIT.

Show solution (0 XP)
IDENTIFICATION DIVISION.
PROGRAM-ID. SortNames.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT WORK-FILE ASSIGN TO "work8.tmp".
DATA DIVISION.
FILE SECTION.
SD  WORK-FILE.
01  WORK-REC.
    05 WORK-NAME PIC X(10).
WORKING-STORAGE SECTION.
01  WS-EOF PIC X VALUE 'N'.
PROCEDURE DIVISION.
    SORT WORK-FILE
        ON ASCENDING KEY WORK-NAME
        INPUT PROCEDURE IS LOAD-DATA
        OUTPUT PROCEDURE IS READ-DATA.
    STOP RUN.

LOAD-DATA SECTION.
    MOVE "Charlie" TO WORK-NAME. RELEASE WORK-REC.
    MOVE "Alice" TO WORK-NAME. RELEASE WORK-REC.
    MOVE "Bob" TO WORK-NAME. RELEASE WORK-REC.
    EXIT.

READ-DATA SECTION.
READ-LOOP.
    RETURN WORK-FILE
        AT END MOVE 'Y' TO WS-EOF
        NOT AT END DISPLAY WORK-NAME
    END-RETURN
    IF WS-EOF = 'N' GO TO READ-LOOP.
    EXIT.