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.
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
Your 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
Your 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 outputcobol
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
You predicted
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
Your output
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
Your output
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
Your 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
Your output
Edge Cases
Identical Keys: If multiple records have identical keys, their relative order after SORT is not guaranteed unless the WITH DUPLICATES IN ORDER clause is specified.
Illegal RETURN: A RETURN statement must only be executed inside an OUTPUT PROCEDURE. Executing it elsewhere causes a runtime error.
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.