SORT dan MERGE

Pengurutan berkas dengan SORT dan penyatuan dengan MERGE, termasuk INPUT dan OUTPUT PROCEDURE.

Daftar isi

SORT dan MERGE adalah dua verb berkas yang menghasilkan berkas terurut tanpa perlu menulis algoritma pengurutan sendiri. Topik ini membahas deklarasi berkas kerja dengan entri SD, bentuk SORT paling umum dengan USING dan GIVING, bentuk prosedural dengan INPUT PROCEDURE dan OUTPUT PROCEDURE yang memakai RELEASE dan RETURN, serta MERGE untuk menyatukan dua berkas yang sudah terurut. Seluruhnya didemonstrasikan pada berkas transaksi yang nyata, mulai dari berkas yang belum terurut sampai dua berkas terurut yang digabungkan. Setelah membacanya, pengurutan berkas dan penyatuannya dapat dipercayakan kepada runtime dengan pengendalian yang tepat.

Berkas kerja SORT dan entri SD#

SORT bekerja melalui sebuah berkas kerja yang menampung record secara sementara selama proses pengurutan. Berkas kerja dideklarasikan pada FILE SECTION dengan entri SD, bukan FD, karena berkas ini milik verb SORT dan tidak pernah dibuka maupun ditutup secara manual. Record berkas kerja memuat seluruh field data sebagaimana record sumbernya, dan field yang menjadi dasar pengurutan harus berada di dalam record tersebut.

cobol Deklarasi berkas kerja SORT dengan entri SD
       SD  kerja-urut.
       01  r-kerja.
           02 sk-kode  PIC X(7).
           02 sk-nilai PIC 9(6).

Frasa kunci pada pernyataan SORT menunjuk field dalam entri SD itu, misalnya ON DESCENDING KEY sk-nilai, dan lebih dari satu field kunci boleh dituliskan berurutan untuk membentuk pengurutan bertingkat. Arah kunci mengikuti kebutuhan laporan, yaitu ASCENDING untuk urutan naik dan DESCENDING untuk urutan turun. GnuCOBOL menerima bentuk ON ... KEY nama-field tanpa kata IS, dan bentuk inilah yang dipakai pada seluruh contoh topik ini.

SORT dengan USING dan GIVING#

Bentuk SORT yang paling umum menyerahkan seluruh proses kepada satu pernyataan, yaitu USING yang menyebut berkas masukan dan GIVING yang menyebut berkas keluaran. Runtime membuka sendiri kedua berkas tersebut, memindahkan record melalui berkas kerja, mengurutkannya menurut kunci, lalu menutupnya kembali. Berkas masukan contoh berisi lima transaksi dengan nilai yang belum berurutan.

text transaksi.dat
TRX001 150000
TRX002 175000
TRX003 250000
TRX004 110000
TRX005 200000

Program berikut mengurutkan berkas tersebut menurut nilai transaksi secara menurun, menyimpan hasilnya pada transaksi-urut.dat, lalu membaca ulang berkas hasil untuk membuktikan urutannya.

cobol urutkan.cbl
       IDENTIFICATION DIVISION.
       PROGRAM-ID. URUTKAN.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT berkas-masuk ASSIGN TO "transaksi.dat"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT berkas-hasil ASSIGN TO "transaksi-urut.dat"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT kerja-urut ASSIGN TO "kerja-urut.tmp".
       DATA DIVISION.
       FILE SECTION.
       FD  berkas-masuk.
       01  r-masuk.
           02 tx-kode  PIC X(7).
           02 tx-nilai PIC 9(6).
       FD  berkas-hasil.
       01  r-hasil.
           02 hx-kode  PIC X(7).
           02 hx-nilai PIC 9(6).
       SD  kerja-urut.
       01  r-kerja.
           02 sk-kode  PIC X(7).
           02 sk-nilai PIC 9(6).
       WORKING-STORAGE SECTION.
       01  sw-akhir PIC X VALUE "N".
       PROCEDURE DIVISION.
       URUTKAN-DATA.
           SORT kerja-urut
               ON DESCENDING KEY sk-nilai
               USING berkas-masuk
               GIVING berkas-hasil.
       TAMPILKAN-HASIL.
           OPEN INPUT berkas-hasil.
           PERFORM UNTIL sw-akhir = "Y"
               READ berkas-hasil
                   AT END
                       MOVE "Y" TO sw-akhir
                   NOT AT END
                       DISPLAY hx-kode hx-nilai
               END-READ
           END-PERFORM.
           CLOSE berkas-hasil.
           STOP RUN.
text Keluaran
TRX003 250000
TRX005 200000
TRX002 175000
TRX001 150000
TRX004 110000

Kompilasi program dengan perintah berikut, kemudian jalankan ./urutkan.

bash
# kompilasi program pengurut berkas transaksi
cobc -x urutkan.cbl

Keluaran menampilkan lima record dalam urutan nilai menurun dari 250000 sampai 110000, dan urutan yang sama tersimpan pada transaksi-urut.dat yang dihasilkan oleh GIVING. Perhatikan bahwa program tidak pernah memanggil OPEN atas berkas masukan maupun berkas keluaran, karena SORT mengelola keduanya secara menyeluruh. Berkas kerja kerja-urut.tmp juga tidak perlu diurus, karena runtime GnuCOBOL menghapusnya kembali setelah proses pengurutan selesai.

INPUT PROCEDURE dan OUTPUT PROCEDURE#

Bentuk USING dan GIVING memproses berkas secara utuh, sedangkan bentuk prosedural memberi titik masuk bagi logika tersendiri di awal dan di akhir pengurutan. INPUT PROCEDURE menggantikan USING, yaitu program membuka berkas masukannya sendiri, memilih record yang relevan, lalu melepaskannya ke proses pengurutan dengan verb RELEASE. OUTPUT PROCEDURE menggantikan GIVING, yaitu program menerima record yang sudah terurut satu per satu dengan verb RETURN dan menuliskannya sendiri ke berkas keluaran. Bentuk ini dipakai ketika data perlu disaring sebelum diurutkan atau laporan perlu disusun saat record terurut diterima.

cobol Contoh: INPUT PROCEDURE dengan RELEASE
       SIAPKAN-MASUK.
           OPEN INPUT berkas-masuk.
           MOVE "N" TO sw-akhir.
           PERFORM UNTIL sw-akhir = "Y"
               READ berkas-masuk
                   AT END
                       MOVE "Y" TO sw-akhir
                   NOT AT END
                       IF tx-nilai >= 150000
                           MOVE r-masuk TO r-kerja
                           RELEASE r-kerja
                       END-IF
               END-READ
           END-PERFORM.
           CLOSE berkas-masuk.

Program berikut mendemonstrasikan sisi OUTPUT PROCEDURE. SORT tetap memakai USING untuk mengambil seluruh transaksi, tetapi hasil terurutnya diterima oleh prosedur SUSUN-LAPORAN yang menghitung jumlah record, menampilkannya, dan menulisnya ke laporan.txt.

cobol urut-laporan.cbl
       IDENTIFICATION DIVISION.
       PROGRAM-ID. URUT-LAPORAN.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT berkas-masuk ASSIGN TO "transaksi.dat"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT berkas-laporan ASSIGN TO "laporan.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT kerja-urut ASSIGN TO "kerja-urut.tmp".
       DATA DIVISION.
       FILE SECTION.
       FD  berkas-masuk.
       01  r-masuk.
           02 tx-kode  PIC X(7).
           02 tx-nilai PIC 9(6).
       FD  berkas-laporan.
       01  r-laporan.
           02 lx-kode  PIC X(7).
           02 lx-nilai PIC 9(6).
       SD  kerja-urut.
       01  r-kerja.
           02 sk-kode  PIC X(7).
           02 sk-nilai PIC 9(6).
       WORKING-STORAGE SECTION.
       01  sw-akhir  PIC X VALUE "N".
       01  cek-jumlah PIC 9(2) VALUE 0.
       PROCEDURE DIVISION.
       URUTKAN-DATA.
           SORT kerja-urut
               ON DESCENDING KEY sk-nilai
               USING berkas-masuk
               OUTPUT PROCEDURE IS SUSUN-LAPORAN.
           DISPLAY "Total record dikembalikan RETURN: " cek-jumlah.
           STOP RUN.
       SUSUN-LAPORAN.
           OPEN OUTPUT berkas-laporan.
           MOVE "N" TO sw-akhir.
           PERFORM UNTIL sw-akhir = "Y"
               RETURN kerja-urut
                   AT END
                       MOVE "Y" TO sw-akhir
                   NOT AT END
                       ADD 1 TO cek-jumlah
                       DISPLAY "RETURN: " sk-kode sk-nilai
                       MOVE sk-kode TO lx-kode
                       MOVE sk-nilai TO lx-nilai
                       WRITE r-laporan
               END-RETURN
           END-PERFORM.
           CLOSE berkas-laporan.
text Keluaran
RETURN: TRX003 250000
RETURN: TRX005 200000
RETURN: TRX002 175000
RETURN: TRX001 150000
RETURN: TRX004 110000
Total record dikembalikan RETURN: 05

Kompilasi program dengan perintah berikut, kemudian jalankan ./urut-laporan.

bash
# kompilasi program SORT dengan OUTPUT PROCEDURE
cobc -x urut-laporan.cbl

Lima baris RETURN tampil dalam urutan nilai menurun, karena RETURN hanya menyerahkan record yang telah selesai diurutkan oleh SORT. Baris terakhir menunjukkan penghitung yang diisi di dalam prosedur, dan nilainya dapat dicantumkan sebagai jumlah record pada laporan. Berbeda dengan GIVING, berkas laporan.txt dibuka dan ditutup oleh prosedur itu sendiri karena penulisan hasil sepenuhnya menjadi tanggung jawab OUTPUT PROCEDURE.

MERGE untuk penyatuan dua berkas terurut#

MERGE menyatukan dua atau lebih berkas masukan yang sudah terurut menurut kunci yang sama menjadi satu berkas keluaran yang tetap terurut. Prosedurnya bekerja dengan membandingkan record terdepan dari setiap masukan, mengambil yang kuncinya paling awal, lalu mengulangi prosesnya sampai seluruh masukan habis. Syarat keterurutan bukan formalitas yang bisa diabaikan, karena MERGE tidak memeriksa urutan masukan. Dua berkas berikut sudah terurut menurut kode transaksi dan sengaja dipecah menjadi dua bagian.

text transaksi-a.dat
TRX001 150000
TRX003 250000
TRX005 200000
text transaksi-b.dat
TRX002 175000
TRX004 110000
TRX006 300000

Program berikut menggabungkan keduanya menjadi transaksi-gabung.dat dengan kunci kode transaksi menaik, lalu membaca ulang hasilnya sebagai bukti.

cobol gabung.cbl
       IDENTIFICATION DIVISION.
       PROGRAM-ID. GABUNG.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT berkas-a ASSIGN TO "transaksi-a.dat"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT berkas-b ASSIGN TO "transaksi-b.dat"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT berkas-gabung ASSIGN TO "transaksi-gabung.dat"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT kerja-gabung ASSIGN TO "kerja-gabung.tmp".
       DATA DIVISION.
       FILE SECTION.
       FD  berkas-a.
       01  r-a.
           02 ax-kode  PIC X(7).
           02 ax-nilai PIC 9(6).
       FD  berkas-b.
       01  r-b.
           02 bx-kode  PIC X(7).
           02 bx-nilai PIC 9(6).
       FD  berkas-gabung.
       01  r-gabung.
           02 gx-kode  PIC X(7).
           02 gx-nilai PIC 9(6).
       SD  kerja-gabung.
       01  r-kerja.
           02 gk-kode  PIC X(7).
           02 gk-nilai PIC 9(6).
       WORKING-STORAGE SECTION.
       01  sw-akhir PIC X VALUE "N".
       PROCEDURE DIVISION.
       GABUNGKAN-DATA.
           MERGE kerja-gabung
               ON ASCENDING KEY gk-kode
               USING berkas-a berkas-b
               GIVING berkas-gabung.
       TAMPILKAN-HASIL.
           OPEN INPUT berkas-gabung.
           PERFORM UNTIL sw-akhir = "Y"
               READ berkas-gabung
                   AT END
                       MOVE "Y" TO sw-akhir
                   NOT AT END
                       DISPLAY gx-kode gx-nilai
               END-READ
           END-PERFORM.
           CLOSE berkas-gabung.
           STOP RUN.
text Keluaran
TRX001 150000
TRX002 175000
TRX003 250000
TRX004 110000
TRX005 200000
TRX006 300000

Kompilasi program dengan perintah berikut, kemudian jalankan ./gabung.

bash
# kompilasi program penyatu dua berkas terurut
cobc -x gabung.cbl

Keluaran memuat enam record dari kedua sumber dalam satu urutan kode menaik, tanpa satu baris pun kode penggabungan yang ditulis sendiri. USING pada MERGE menyebut dua berkas sekaligus dan wajib memuat minimal dua nama, sedangkan GIVING berperan sama seperti pada SORT. Ketika salah satu berkas sumber habis lebih dulu, record tersisa dari sumber lain disalin berurutan, sehingga penggabungan berkas harian dari beberapa mesin menjadi penerapan yang wajar.

Kesalahan umum#

  • Masukan MERGE tidak terurut menurut kunci yang sama. MERGE hanya membandingkan record terdepan setiap masukan, sehingga hasilnya salah urut tanpa satu pesan error pun. Pastikan kedua berkas sumber dihasilkan dengan urutan kunci yang identik dengan frasa kunci MERGE.
  • Field kunci tidak berada di dalam record entri SD. Frasa KEY menunjuk field pada record berkas kerja, dan compiler menolak deklarasi yang menunjuk field di luar entri SD. Salin struktur record sumber ke entri SD, lalu tunjuk fieldnya pada frasa kunci.
  • Berkas pada USING dan GIVING dibuka atau ditutup secara manual. SORT dan MERGE mengelola kedua berkas itu dari awal sampai akhir, sehingga pembukaan atau penutupan manual berujung pada status berkas yang salah. Biarkan verb yang membuka dan menutupnya, dan tulis OPEN hanya untuk berkas keluaran di dalam OUTPUT PROCEDURE.

Ringkasan#

  • SORT memerlukan berkas kerja berentri SD yang recordnya memuat field kunci, dan bentuk USING GIVING menangani pembukaan serta penutupan berkas masukan dan keluaran secara otomatis.
  • INPUT PROCEDURE menyaring masukan lewat RELEASE, sedangkan OUTPUT PROCEDURE menerima hasil terurut lewat RETURN dan menulis keluarannya sendiri.
  • MERGE menyatukan dua berkas atau lebih yang sudah terurut menurut kunci yang sama, dengan USING minimal dua berkas dan GIVING satu keluaran.
  • Berkas kerja dikelola penuh oleh runtime GnuCOBOL dan dihapus kembali setelah prosesnya selesai.

Referensi#