Berkas terindeks mengizinkan program mencapai sebuah record secara langsung melalui kunci logisnya, tanpa membaca record lain di depannya. Topik ini membahas deklarasi RECORD KEY dan ALTERNATE RECORD KEY beserta klausa DUPLICATES, akses RANDOM dengan penanganan INVALID KEY, akses DYNAMIC dengan START dan READ NEXT, serta DELETE untuk menghapus record menurut kuncinya. Seluruhnya didemonstrasikan pada satu berkas kartu anggota yang dibangun oleh program pertama, kemudian dibaca, ditelusuri, dan dihapus sebagian recordnya oleh program kedua. Setelah membacanya, berkas terindeks dapat dibuat dan diakses dengan kebijakan kunci yang tepat.
Kunci utama dan kunci alternatif#
Berkas terindeks dideklarasikan dengan ORGANIZATION IS INDEXED dan wajib memiliki satu kunci utama berupa field di dalam record yang isinya membedakan setiap record. Deklarasi berikut memakai kode anggota sebagai kunci utama dan nama sebagai kunci alternatif.
SELECT berkas-anggota ASSIGN TO "anggota.dat"
ORGANIZATION IS INDEXED
ACCESS IS RANDOM
RECORD KEY IS fk-kode
ALTERNATE RECORD KEY IS fk-nama
FILE STATUS IS fs-anggota.Kunci utama (RECORD KEY) selalu unik, sehingga program menolak dua record dengan nilai kunci yang sama. Kunci alternatif (ALTERNATE RECORD KEY) dapat ditulis lebih dari satu, dan unik atau tidaknya ditentukan oleh klausa DUPLICATES. Tanpa klausa itu, duplikasi nilai kunci alternatif ditolak seperti kunci utama, sedangkan dengan klausa tersebut, misalnya ALTERNATE RECORD KEY IS fk-kota WITH DUPLICATES, beberapa record boleh berbagi nilai yang sama. Kunci utama tidak boleh berubah nilai pada REWRITE karena perubahan kunci berarti memindahkan record ke posisi lain, dan hal semacam itu dilakukan lewat kombinasi DELETE dan WRITE.
Bentuk fisiknya memunculkan berkas tambahan di direktori kerja. GnuCOBOL menyimpan record beserta kunci utamanya pada anggota.dat, sedangkan setiap kunci alternatif memperoleh berkas indeks tersendiri yang diberi nomor menurut urutan deklarasinya, yaitu anggota.dat.1 untuk kunci alternatif pertama dan anggota.dat.2 untuk yang berikutnya. Berkas bernomor itu bukan berkas sisa, melainkan peta pencarian kunci alternatif, sehingga anggota.dat dan berkas bernomor itu wajib dipindahkan dan dihapus berpasangan.
Membangun berkas dan menolak kunci ganda#
Program pertama mengisi empat record anggota, kemudian sengaja mencoba dua penulisan yang salah untuk memperlihatkan penanganan INVALID KEY. Keempat record diisi melalui tabel dan PERFORM, sedangkan dua percobaan terakhir menulis record dengan nama yang sudah dipakai dan kode yang sudah dipakai.
IDENTIFICATION DIVISION.
PROGRAM-ID. BUAT-INDEKS.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT berkas-anggota ASSIGN TO "anggota.dat"
ORGANIZATION IS INDEXED
ACCESS IS RANDOM
RECORD KEY IS fk-kode
ALTERNATE RECORD KEY IS fk-nama
FILE STATUS IS fs-anggota.
DATA DIVISION.
FILE SECTION.
FD berkas-anggota.
01 r-anggota.
02 fk-kode PIC X(4).
02 fk-nama PIC X(12).
02 fd-nilai PIC 9(3).
WORKING-STORAGE SECTION.
01 fs-anggota PIC XX.
01 dt-anggota.
02 dt-baris OCCURS 4 TIMES.
03 dt-kode PIC X(4).
03 dt-nama PIC X(12).
03 dt-nilai PIC 9(3).
01 i PIC 9.
PROCEDURE DIVISION.
ISI-TABEL.
MOVE "A001Ali 080" TO dt-baris (1).
MOVE "A002Budi 075" TO dt-baris (2).
MOVE "A003Citra 090" TO dt-baris (3).
MOVE "A004Dewi 085" TO dt-baris (4).
TULIS-RECORD.
OPEN OUTPUT berkas-anggota.
PERFORM VARYING i FROM 1 BY 1 UNTIL i > 4
MOVE dt-baris (i) TO r-anggota
WRITE r-anggota
INVALID KEY
DISPLAY "WRITE " fk-kode " ditolak, status "
fs-anggota
NOT INVALID KEY
DISPLAY "WRITE " fk-kode " berhasil"
END-WRITE
END-PERFORM.
UJI-KUNCI-GANDA.
MOVE "A005" TO fk-kode.
MOVE "Budi" TO fk-nama.
MOVE 070 TO fd-nilai.
WRITE r-anggota
INVALID KEY
DISPLAY "WRITE A005 ditolak, status " fs-anggota
NOT INVALID KEY
DISPLAY "WRITE A005 berhasil"
END-WRITE.
MOVE "A001" TO fk-kode.
MOVE "Eka" TO fk-nama.
MOVE 078 TO fd-nilai.
WRITE r-anggota
INVALID KEY
DISPLAY "WRITE A001 ditolak, status " fs-anggota
NOT INVALID KEY
DISPLAY "WRITE A001 berhasil"
END-WRITE.
CLOSE berkas-anggota.
STOP RUN.WRITE A001 berhasil
WRITE A002 berhasil
WRITE A003 berhasil
WRITE A004 berhasil
WRITE A005 ditolak, status 22
WRITE A001 ditolak, status 22Kompilasi program dengan perintah berikut, kemudian jalankan ./buat-terindeks.
# kompilasi program pembangun berkas terindeks
cobc -x buat-terindeks.cblEmpat baris pertama menunjukkan penulisan yang bersih, sedangkan dua baris terakhir memperlihatkan penolakan dengan status 22, yaitu kode status untuk kunci ganda. WRITE A005 ditolak karena nama Budi sudah dipakai oleh A002 pada kunci alternatif yang tidak diberi klausa DUPLICATES, sedangkan WRITE A001 ditolak karena kodenya menabrak kunci utama record yang sudah ada. Frasa INVALID KEY menangkap kedua kegagalan itu dan menjalankan cabang penanganannya, sehingga program tetap berjalan dan berkas bebas dari record ganda.
Akses DYNAMIC dengan START dan DELETE#
Program kedua membuka berkas yang sama dengan mode I-O dan akses DYNAMIC, sehingga pembacaan acak, telusuran berurutan, dan penghapusan dapat berseling di dalam satu pembukaan berkas.
IDENTIFICATION DIVISION.
PROGRAM-ID. AKSES-INDEKS.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT berkas-anggota ASSIGN TO "anggota.dat"
ORGANIZATION IS INDEXED
ACCESS IS DYNAMIC
RECORD KEY IS fk-kode
ALTERNATE RECORD KEY IS fk-nama
FILE STATUS IS fs-anggota.
DATA DIVISION.
FILE SECTION.
FD berkas-anggota.
01 r-anggota.
02 fk-kode PIC X(4).
02 fk-nama PIC X(12).
02 fd-nilai PIC 9(3).
WORKING-STORAGE SECTION.
01 fs-anggota PIC XX.
01 sw-akhir PIC X VALUE "N".
PROCEDURE DIVISION.
BACA-LEWAT-KUNCI.
OPEN I-O berkas-anggota.
MOVE "A003" TO fk-kode.
READ berkas-anggota
INVALID KEY
DISPLAY "READ A003 gagal, status " fs-anggota
NOT INVALID KEY
DISPLAY "Baca kunci utama : " fk-kode " "
fk-nama
END-READ.
MOVE "Dewi" TO fk-nama.
READ berkas-anggota KEY IS fk-nama
INVALID KEY
DISPLAY "READ Dewi gagal, status " fs-anggota
NOT INVALID KEY
DISPLAY "Baca kunci alternatif : " fk-kode " "
fk-nama
END-READ.
MOVE "Z999" TO fk-kode.
READ berkas-anggota
INVALID KEY
DISPLAY "READ Z999 gagal, status " fs-anggota
NOT INVALID KEY
DISPLAY "READ Z999 berhasil"
END-READ.
MULAI-DAN-SAPU.
MOVE "A002" TO fk-kode.
START berkas-anggota KEY IS NOT LESS THAN fk-kode
INVALID KEY
DISPLAY "START gagal, status " fs-anggota
NOT INVALID KEY
DISPLAY "START dari A002 berhasil"
END-START.
MOVE "N" TO sw-akhir.
PERFORM UNTIL sw-akhir = "Y"
READ berkas-anggota NEXT RECORD
AT END
MOVE "Y" TO sw-akhir
NOT AT END
DISPLAY " " fk-kode " " fk-nama " " fd-nilai
END-READ
END-PERFORM.
HAPUS-RECORD.
MOVE "A002" TO fk-kode.
DELETE berkas-anggota RECORD
INVALID KEY
DISPLAY "DELETE A002 gagal, status " fs-anggota
NOT INVALID KEY
DISPLAY "DELETE A002 berhasil"
END-DELETE.
MOVE "X000" TO fk-kode.
DELETE berkas-anggota RECORD
INVALID KEY
DISPLAY "DELETE X000 gagal, status " fs-anggota
NOT INVALID KEY
DISPLAY "DELETE X000 berhasil"
END-DELETE.
CLOSE berkas-anggota.
STOP RUN.Baca kunci utama : A003 Citra
Baca kunci alternatif : A004 Dewi
READ Z999 gagal, status 23
START dari A002 berhasil
A002 Budi 075
A003 Citra 090
A004 Dewi 085
DELETE A002 berhasil
DELETE X000 gagal, status 23Kompilasi program kedua, kemudian jalankan ./akses-terindeks.
# kompilasi program akses berkas terindeks
cobc -x akses-terindeks.cblDua baris pertama memperlihatkan dua jalur pembacaan, yaitu READ yang menunjuk kunci utama dan READ dengan frasa KEY IS yang menunjuk kunci alternatif. Pembacaan Z999 gagal dengan status 23, yaitu kode untuk kunci yang tidak ditemukan. START memosisikan berkas pada record pertama dengan kunci NOT LESS THAN A002, kemudian READ NEXT mengambil record satu per satu menurut urutan kunci utama hingga AT END, sehingga penelusurannya terbukti mengikuti urutan logis dan bukan urutan penulisan. DELETE menghapus record A002 yang kuncinya dimuat pada field kunci, sedangkan percobaan menghapus X000 ditolak dengan status 23 karena kuncinya tidak ada.
Kesalahan umum#
- INVALID KEY tidak disediakan pada operasi kunci. Tanpa frasa ini, penulisan atau pembacaan yang gagal hanya tampak pada
FILE STATUS, sehingga record yang ditolak mudah dianggap berhasil diproses. Sediakan INVALID KEY atau periksa status berkas setelah setiap operasi kunci. - READ NEXT dijalankan sebelum START atau sesudah pembacaan acak yang gagal. Posisi awal penelusuran tidak terdefinisi dalam keadaan tersebut, sehingga record yang diperoleh tidak dapat dipastikan. Panggil START untuk memosisikan berkas sebelum penelusuran berurutan dimulai.
- Berkas indeks bernomor seperti anggota.dat.1 dianggap sampah dan ikut terhapus. Berkas itu menyimpan peta kunci alternatif, dan hilangnya membuat pembacaan lewat kunci alternatif gagal. Pindahkan atau hapus anggota.dat dan anggota.dat.1 selalu sebagai satu paket.
Ringkasan#
- Berkas terindeks wajib memiliki
RECORD KEYyang unik, danALTERNATE RECORD KEYmenambah jalur akses lain yang boleh menggunakan klausaDUPLICATES. - GnuCOBOL menyimpan data dengan kunci utamanya pada anggota.dat dan memberi setiap kunci alternatif berkas indeks bernomor di sampingnya.
- Akses
RANDOMmenangkap kunci ganda dan kunci yang tidak ada melalui INVALID KEY dengan status 22 dan 23, sedangkan aksesDYNAMICmemadukan START, READ NEXT, READ acak, dan DELETE pada satu pembukaan berkas. - Penelusuran berurutan mengikuti urutan nilai kunci, bukan urutan record ditulis.
Referensi#
- GnuCOBOL — Free Software Foundation — Situs proyek GnuCOBOL 3.2 yang menjalankan seluruh contoh berkas terindeks pada topik ini.
- GnuCOBOL Manual — Free Software Foundation — Manual resmi GnuCOBOL yang memuat klausa RECORD KEY, ALTERNATE RECORD KEY, dan verb START serta DELETE.
- IBM Enterprise COBOL for z/OS documentation — IBM — Dokumentasi resmi berkas terindeks, frasa INVALID KEY, dan kode status berkas pada COBOL komputer pusat.