Programmeren in COBOL/Bestandsorganisatie/Printversie

Uit Wikibooks
Deel III: Bestandsorganisatie





In dit deel van het boek wordt bekeken hoe je met COBOL kunt omgaan met verschillende bestandsorganisaties. Zoals gewone sequentiële bestanden en relative bestanden.

De inhoud van dit deel[bewerken]

  1. Sequentiële bestanden Zeer goed ontwikkeld. Revisiedatum: 21 oktober 2007 (Oef Redelijk ontwikkeld. Revisiedatum: 21 oktober 2007 )
  2. Relatieve bestanden zonder hash Zeer goed ontwikkeld. Revisiedatum: 20 november 2007 (Oef Nog vrijwel niets. Revisiedatum: 20 november 2007 )
  3. Relatieve bestanden met hash Goed ontwikkeld. Revisiedatum: 21 oktober 2007 (Oef Nog vrijwel niets. Revisiedatum: 23 november 2007 )
  4. Index-sequentiële bestanden Nog vrijwel niets. Revisiedatum: 21 oktober 2007 (Oef Nog vrijwel niets. Revisiedatum: 20 november 2007 )


 


1. Sequentiële bestanden



Dit is een hoofdstuk van Programmeren in COBOL. Hier zul je leren hoe je sequentiële bestanden kunt lezen.

Voorbeeld van een sequentieel bestand[bewerken]

Een sequentieel bestand is een bestand waar iedere lijn een record vormt. Een record zal gegevens opslaan voor bijvoorbeeld één persoon. Een sequentieel bestand kan verschillende datatypes (of extensies) hebben. Wij zullen .txt gebruiken. Maar dat kan natuurlijk ook .dat of .in of iets anders zijn.

COBOL-code: Sequentieel bestand

Peeters             Jan            Kerkplein 8               ZAVENTEM      M
Jansen              Peter          Stationstraat 124         KAMPENHOUT    M

In dit sequentieel bestand worden de naam, adres en geslacht van een persoon opgeslagen.

Sequentiële bestanden lezen[bewerken]

  Zie ook READ voor meer informatie.

We gaan een klein programma schrijven dat de gegevens inleest en alleen de achternaam, voornaam en geslacht op het scherm toont.

COBOL-code: Sequentieel bestand lezen

       IDENTIFICATION DIVISION.
       PROGRAM-ID. seqbestanlezen.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT invoer ASSIGN TO "invoer.txt"
           LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD invoer.
       01 persoon.
        02 achternaam  PIC X(20).
        02 voornaam    PIC X(15).
        02 adres       PIC X(26).
        02 plaats      PIC X(14).
        02 geslacht    PIC X.

       WORKING-STORAGE SECTION.
       77       PIC X  VALUE "n".
         88 eof        VALUE "j".

       PROCEDURE DIVISION.
       HOOFD.
           OPEN INPUT invoer
           READ invoer AT END SET eof TO TRUE END-READ
           PERFORM lees UNTIL eof
           CLOSE invoer
           STOP RUN.

       LEES.
           DISPLAY voornaam " " achternaam " " geslacht
           READ invoer AT END SET eof TO TRUE END-READ
           .
Jan             Peeters              M
Peter           Jansen               M

Nu gaan we dat een beetje uitleggen.

COBOL-code: Sequentieel bestand lezen

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT invoer ASSIGN TO "invoer.txt"
           LINE SEQUENTIAL.

Als er gewerkt wordt met bestanden wordt dit stukje toegevoegd. Het bestand invoer.txt wordt gekoppeld met invoer wat belangrijk is in de DATA DIVISION. LINE SEQUENTIAL geeft aan dat het een sequentieel bestand is.

COBOL-code: Sequentieel bestand lezen

       DATA DIVISION.
       FILE SECTION.
       FD invoer.
       01 persoon.
        02 achternaam PIC X(20).
        02 voornaam PIC X(15).
        02 geslacht PIC X.

In de DATA DIVISION komt er de FILE SECTION bij. Er wordt gebruik gemaakt van groepsvelden om de gegevens in op te slaan. In dit geval is dat persoon.

COBOL-code: Sequentieel bestand lezen

           OPEN INPUT invoer
           READ invoer AT END SET eof TO TRUE END-READ

In de programmacode moet het bestand eerst worden geopend. Dit doe je met OPEN INPUT, gevolgd door de naam van het bestand. Daarna doe je een READ. De boolean eof is nodig voor een lus. Als je op het einde van een bestand zit, wordt deze op TRUE gezet. Daardoor kan een lus weten wanneer je op het einde zit. Een READ leest slechts één record in één keer. Alle gegevens worden dan in het groepsveld persoon gezet. Wanneer je daarna nog een READ doet, gaat hij naar het volgende record en gaan de gegevens van het vorige verloren.

COBOL-code: Sequentieel bestand lezen

           PERFORM lees UNTIL eof

Dit is een verwijzing naar een deelprogramma maar ook een lus. Dit zal het deelprogramma blijven uitvoeren tot het aan het einde is van het bestand. Hiervoor wordt de variabele eof gebruikt, als die op true gezet wordt, eindigt de lus.

COBOL-code: Sequentieel bestand lezen

       LEES.
           DISPLAY voornaam " " achternaam " " geslacht
           READ invoer AT END SET eof TO TRUE END-READ
           .

Dit is het deelprogramma. Eerst toont het op het scherm wat het de vorige keer uit het bestand heeft gelezen. Daarna leest het een nieuwe record.

COBOL-code: Sequentieel bestand lezen

           CLOSE invoer

Nadat je gedaan hebt met het lezen van het bestand, moet je het bestand terug sluiten met CLOSE.

Sequentiële bestanden schrijven[bewerken]

  Zie ook WRITE voor meer informatie.

Een bestand schrijven volgt natuurlijk het omgekeerde principe van een bestand lezen. Je verwerkt eerst de gegevens je plaatst die in het groepsveld van de uitvoer en vervolgens schrijf je het bestand. We zullen in dit voorbeeld een bestand openen en daarna lezen wat er in zit om dat te verwerken en uit te schrijven. Je moet natuurlijk niet een bestand lezen; je kan gewoon de gegevens inlezen via een ACCEPT, maar dat neemt tijd in beslag. We gebruiken in dit voorbeeld hetzelfde sequentieel bestand om te lezen als in het vorige.

COBOL-code: Sequentieel bestand schrijven

       IDENTIFICATION DIVISION.
       PROGRAM-ID. seqbestanschrijven.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT invoer ASSIGN TO "invoer.txt"
           LINE SEQUENTIAL.

           SELECT uitvoer ASSIGN to "uitvoer.txt"
           LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD invoer.
       01 persoon.
        02 achternaam PIC X(20).
        02 voornaam   PIC X(15).
        02 geslacht   PIC X.


       FD uitvoer.
       01 regel.
        02 uitvn PIC X(15).
        02       PIC X.
        02 uitan PIC X(20).
        02       PIC X.
        02 uitge PIC X.

       WORKING-STORAGE SECTION.
       77        PIC X  VALUE "n".
         88 eof         VALUE "j".

       PROCEDURE DIVISION.
       HOOFD.
           OPEN INPUT invoer
           OPEN OUTPUT uitvoer
           READ invoer AT END SET eof TO TRUE END-READ
           PERFORM lees UNTIL eof

           CLOSE invoer
           CLOSE uitvoer
           STOP RUN.

       LEES.
           MOVE achternaam TO uitan
           MOVE voornaam TO uitvn
           MOVE geslacht TO uitge
           WRITE regel END-WRITE
           DISPLAY voornaam " " achternaam " " geslacht
           READ invoer AT END SET eof TO TRUE END-READ
           .

Een uitvoer-bestand wordt op dezelfde manier gekoppeld met een groepsveld en ook op dezelfde manier gesloten. Het bestand openen gebeurt op een andere manier "OPEN OUTPUT uitvoer". In COBOL wordt namelijk een bestand gelezen, terwijl een record geschreven wordt.

COBOL-code: Sequentieel bestand schrijven

           MOVE achternaam TO uitan
           MOVE voornaam TO uitvn
           MOVE geslacht TO uitge
           WRITE regel END-WRITE

Het enige waar er moet op gelet worden, is het overzetten van de variabelen van het éne groepsveld naar het andere en ook de WRITE-commando gevolgd door de groepsveld van de uitvoer en de END-WRITE. Hieronder bevindt zicht het resultaat van dit programma.

Jan             Peeters              M
Peter           Jansen               M

Record achteraan toevoegen[bewerken]

Telkens we OPEN OUTPUT doen en we schrijven daar iets in wordt er eigenlijk een nieuw bestand opgeslagen m.a.w. als er al een bestand bestond met dezelfde naam gaan de gegevens in dat bestand verloren en wordt het vervangen door andere gegevens. Daardoor kun je geen record toevoegen met OPEN OUTPUT hievoor moet je OPEN EXTEND gebruiken. OPEN EXTEND betekent dat je automatisch vanachter gegevens kunt toevoegen. In dit volgende programma gaat de gebruiker gegevens van een persoon opgeven en die worden achteraan toegevoegd.

COBOL-code: Record achteraan toevoegen.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. RecordToevoegen.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT uitvoer ASSIGN to "uitvoer.txt"
           LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD uitvoer.
       01 regel.
        02 uitvn PIC X(15).
        02       PIC X.
        02 uitan PIC X(20).
        02       PIC X.
        02 uitge PIC X.

       WORKING-STORAGE SECTION.
       77        PIC X  VALUE "n".
         88 eof         VALUE "j".

       PROCEDURE DIVISION.
       HOOFD.
           OPEN EXTEND uitvoer
           DISPLAY "Geef de voornaam:"
           ACCEPT uitvn NO BEEP
           DISPLAY "Geef de achternaam:"
           ACCEPT uitan NO BEEP
           DISPLAY "Geef het geslacht:"
           ACCEPT uitge NO BEEP
           WRITE regel END-WRITE
           CLOSE uitvoer
           STOP RUN.

Niet zo moeilijk, dus gewoon in de plaats van OPEN OUTPUT moet je OPEN EXTEND gebruiken.

Record herschrijven[bewerken]

  Zie ook REWRITE voor meer informatie.

Het is mogelijk bij een sequentieel bestand een record te herschrijven. Dit is echter onpraktisch. Als je één bepaald record wilt aanpassen heb je twee keuzes: ofwel ga je alle records één voor één af tot je de juiste record hebt gevonden, ofwel schrijf je een programma dat zelf alle records afgaat en vind wat je zoekt. Daardoor zijn sequentiële bestanden niet de goede oplossing als je weet dat je uw records vaak zult moeten aanpassen. Hiervoor zijn betere bestandsorganisaties die later nog aan bod komen. In het volgende programma krijgt de gebruiker ieder record te zien en wordt hem gevraagd of hij ze wilt herschrijven.

COBOL-code: Record herschrijven.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. recordHerschrijven.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT bestand ASSIGN TO "uitvoer.txt"
           LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD bestand.
       01 regel.
        02 voornaam   PIC X(15).
        02            PIC X.
        02 achternaam PIC X(20).
        02            PIC X.
        02 geslacht   PIC X.

       WORKING-STORAGE SECTION.
       77        PIC X  VALUE "n".
         88 eof         VALUE "j".
       77 invoer PIC X.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN I-O bestand
           READ bestand AT END SET eof TO TRUE END-READ
           PERFORM herschrijf UNTIL eof
           CLOSE bestand
           STOP RUN.

       HERSCHRIJF.
           DISPLAY voornaam " " achternaam " " geslacht
           DISPLAY "Wilt u de gegevens van deze persoon aanpassen"
                   "(0=neen)"
           ACCEPT invoer NO BEEP
           IF invoer = 0
             THEN DISPLAY "Geen gegevens aangepast"
             ELSE 
              DISPLAY "Geef de voornaam:"
              ACCEPT voornaam NO BEEP
              DISPLAY "Geef de achternaam:"
              ACCEPT achternaam NO BEEP
              DISPLAY "Geef het geslacht:"
              ACCEPT geslacht NO BEEP
              REWRITE regel END-REWRITE
           END-IF
           READ bestand AT END SET eof TO TRUE END-READ
           .

Een record herschrijven op zich is niet zo moeilijk. Er zijn twee dingen waar je wel voor moet opletten. I-O of INPUT-OUTPUT dit betekent dat een bestand zal worden gezien als invoer en als uitvoer. Dit komt omdat je eerst de records moet lezen voor je ze kan herschrijven. Je moet dus altijd I-O of INPUT-OUTPUT gebruiken als je iets wilt herschrijven. Voor je iets kunt herschrijven moet je eerst iets lezen met de READ en vervolgens herschrijf je het met de REWRITE. REWRITE werkt hetzelde als WRITE.

Record verwijderen[bewerken]

Je kunt bij sequentiële bestanden geen records verwijderen. Wat je echter wel kunt doen is de record herschrijven en opvullen met spaties. Je kunt dan een beveiliging inbouwen zodat wanneer de record wordt gelezen die bijvoorbeeld wordt overgeslagen. Je hoeft natuurlijk je record niet opvullen met spaties dit mag natuurlijk ook iets anders zijn of in ieder geval één of ander kenmerk zodat je programma weet dat deze record moet worden overgeslagen.


2. Relatieve bestanden zonder hash



Bij sequentiële bestanden is het moeilijk om een bepaald record terug te vinden. De enige optie is om dan record per record te lezen tot je het vindt. Dat is natuurlijk niet echt handig en efficiënt. Daarom bestaan er relatieve bestanden. Een record in een relatief bestand zal een nummer krijgen : de zogenaamde relatieve sleutel van 1 tot n. Via een bepaalde berekening kan COBOL bepalen waar deze record zich in het bestand bevindt. Een relatief bestand kan op 3 manieren worden gelezen. SEQUENTIAL zoals een sequentieel bestand. RANDOM wat betekent dat je een nummer ingeeft en de record wordt opgehaald met dat nummer. En DYNAMIC dit is een combinatie van de twee vorige.

Relatief bestand aanmaken[bewerken]

Een relatief bestand kun je niet in een tekstverwerker aanmaken. Je moet het via een programma aanmaken dat je zelf hebt geschreven.

COBOL-code: Relatief bestand aanmaken

       IDENTIFICATION DIVISION.
       PROGRAM-ID. relatief.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT persoon ASSIGN TO "persoon.dat"
               ORGANIZATION LINE SEQUENTIAL
               ACCESS SEQUENTIAL.

           SELECT persoonrel ASSIGN TO "persoonrel.dat"
               ORGANIZATION RELATIVE
               ACCESS SEQUENTIAL
               RELATIVE KEY persoonnummer.

       DATA DIVISION.
       FILE SECTION.
       FD persoon.
       01 gegevens PIC X(50).

       FD persoonrel.
       01 gegevensrel PIC X(50).

       WORKING-STORAGE SECTION.
       77               PIC X.
        88 eof          VALUE "j", "J".
       01 persoonnummer PIC 99.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN INPUT persoon
           OPEN OUTPUT persoonrel

           DISPLAY "persoonnummer    persoonnaam"
           READ persoon AT END SET eof TO TRUE END-READ

           PERFORM UNTIL eof
               MOVE gegevens TO gegevensrel
               WRITE gegevensrel END-WRITE
               DISPLAY persoonnummer "               " gegevensrel
               READ persoon AT END SET eof TO TRUE END-READ
           END-PERFORM
           STOP RUN.

Dit is dus een voorbeeld van een programma dat relatieve bestanden aanmaakt. We lezen hier een sequentieel bestand om vervolgens het relatief bestand aan te maken.

COBOL-code: Relatief bestand aanmaken

Jan       Peeters
Peter     Pieters
Piet      Jansen

Dit is het sequentieel bestand. Je kunt natuurlijk ook de gegevens inlezen via ACCEPT maar als uw programma onverwacht fouten bevat moet je de gegevens opnieuw ingeven. Via een sequentieel bestand te lezen vermijd je onnodig werk. Nu gaan we een beetje de code uitleggen.

COBOL-code: Relatief bestand aanmaken

       FILE-CONTROL.
           SELECT persoon ASSIGN TO "persoon.dat"
               ORGANIZATION LINE SEQUENTIAL
               ACCESS SEQUENTIAL.

           SELECT persoonrel ASSIGN TO "persoonrel.dat"
               ORGANIZATION RELATIVE
               ACCESS SEQUENTIAL
               RELATIVE KEY persoonnummer.

Bij FILE-CONTROL zijn veel dingen toegevoegd. ORGANIZATION geeft aan wat voor een bestand het is, LINE SEQUENTIAL voor sequentiële bestanden en RELATIVE voor relatieve bestanden. Het is niet verplicht om ORGANIZATION te schrijven maar aangezien we met twee verschillende soorten bestanden werken kan het duidelijker zijn. ACCES geeft aan hoe er met het bestand zal worden gewerkt. Sequentieel is dus record per record. Je zult je waarschijnlijk wel afvragen waarom we het relatieve bestand sequentieel gaan gebruiken en niet RANDOM. Dit is omdat het bestand alleen maar zal worden aangemaakt en zullen we dus record per record aanmaken en achter elkaar plaatsen. RELATIVE KEY zal de sleutel bepalen bij elke record, hier koppelen we deze sleutel met de variabele persoonnummer.

COBOL-code: Relatief bestand aanmaken

       DATA DIVISION.
       FILE SECTION.
       FD persoon.
       01 gegevens    PIC X(50).

       FD persoonrel.
       01 gegevensrel PIC X(50).

       WORKING-STORAGE SECTION.
       77               PIC X.
        88 eof          VALUE "j", "J".
       01 persoonnummer PIC 99.

Er valt niet echt veel te zeggen over de DATA DIVISION. We gaan toch de gegevens niet verwerken dus is het indelen in groepsvelden niet nodig, je zou het wel kunnen doen. Waar je moet opletten is de lengte van de records. Die is hier 50 tekens lang als je dit relatief bestand wilt lezen zal je ook 50 tekens moeten gebruiken anders krijg je foutmeldingen. Waar je ook moet opletten is persoonnummer dat is de relatieve sleutel. Het aantal records dat je kunt opslaan hangt af van deze sleutel de PIC is hier 99 dus kun je maximaal 99 records hebben.

COBOL-code: Relatief bestand aanmaken

           READ persoon AT END SET eof TO TRUE END-READ

           PERFORM UNTIL eof
               MOVE gegevens TO gegevensrel
               WRITE gegevensrel END-WRITE
               DISPLAY persoonnummer "               " gegevensrel
               READ persoon AT END SET eof TO TRUE END-READ
           END-PERFORM

Hier valt ook niet veel te vertellen. Het is grotendeels zoals bij sequentiële bestanden. Het sequentieel bestand wordt gelezen. De gegevens worden overgebracht en de record wordt geschreven in het relatief bestand.

Relatief bestand lezen[bewerken]

  Zie ook READ voor meer informatie.

Relatief bestand sequentieel lezen[bewerken]

COBOL-code: Relatief bestand lezen

       IDENTIFICATION DIVISION.
       PROGRAM-ID. relatief.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT persoon ASSIGN TO "persoonr.dat"
               ORGANIZATION RELATIVE
               ACCESS SEQUENTIAL
               FILE STATUS bestandstatus.

       DATA DIVISION.
       FILE SECTION.
       FD persoon.
       01 gegevens PIC X(50).

       WORKING-STORAGE SECTION.
       77 bestandstatus PIC XX.
        88 eof          VALUE 10.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN INPUT persoon
           READ persoon AT END CONTINUE END-READ

           PERFORM UNTIL eof
               DISPLAY gegevens
               READ persoon AT END CONTINUE END-READ
           END-PERFORM
           CLOSE persoon
           STOP RUN.

We gaan eerst aantonen dat je een relatief bestand ook gewoon sequentieel kunt lezen. Hoewel we een zogenaamde relatieve sleutel hebben zullen we die nog niet gebruiken.

COBOL-code: Relatief bestand lezen

           SELECT persoon ASSIGN TO "persoonr.dat"
               ORGANIZATION RELATIVE
               ACCESS SEQUENTIAL
               FILE STATUS bestandstatus.

Het enige interessante hier is FILE STATUS die geeft aan wat de status is van het bestand. Bijvoorbeeld of het open of gesloten is, of je iets uit het bestand wil lezen terwijl je het hebt geopend om er alleen in te schrijven of zoals we nu gaan zien of het aan het einde is van het bestand en zoverder.

COBOL-code: Relatief bestand lezen

       77 bestandstatus PIC xx.
        88 eof          VALUE 10.

FILE STATUS is gekoppeld aan de variabele bestandstatus. De variabele bestandstatus zal een nummer krijgen naar gelang de status van het bestand. Als het op het einde van het bestand is krijgt het nummer 10. Hierdoor wordt eof(end of file) geactiveerd. Dat is nodig voor de volgende lus

COBOL-code: Relatief bestand lezen

           PERFORM UNTIL eof
               DISPLAY gegevens
               READ persoon AT END CONTINUE END-READ
           END-PERFORM

Hier is niet speciaals te zien behalve de READ. Als het op het einde van het bestand komt gaat het gewoon verder met de programmacode.

Relatief bestand random lezen[bewerken]

COBOL-code: Relatief bestand lezen

       IDENTIFICATION DIVISION.
       PROGRAM-ID. relatief.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

           SELECT persoon ASSIGN TO "persoonr.dat"
               ORGANIZATION RELATIVE
               ACCESS RANDOM
               RELATIVE KEY persoonnummer.

       DATA DIVISION.
       FILE SECTION.
       FD persoon.
       01 gegevens PIC X(50).

       WORKING-STORAGE SECTION.
       77 persoonnummer PIC 99.
        88 stoppen      VALUE 0.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN INPUT persoon
           DISPLAY "Geef nummer van de persoon(0 om te stoppen):"
           ACCEPT persoonnummer NO BEEP

           PERFORM UNTIL stoppen
               READ persoon
               DISPLAY "persoonnummer | gegevens"
               DISPLAY persoonnummer "              " gegevens
               DISPLAY " "
               DISPLAY "Geef nummer van de persoon(0 om te stoppen):"
               ACCEPT persoonnummer NO BEEP
           END-PERFORM
           STOP RUN.

Een relatief bestand RANDOM lezen is vrij makkelijk. Je vraagt aan de gebruiker om de persoonnummer in te geven en dan zoek je de gegevens van die persoon op.

COBOL-code: Relatief bestand lezen

           SELECT persoon ASSIGN TO "persoonr.dat"
               ORGANIZATION RELATIVE
               ACCESS RANDOM
               RELATIVE KEY persoonnummer.

Dit keer gebruiken we dus access random we kunnen om het evenwelke record lezen. Opnieuw is de relatieve sleutel persoonnummer.

COBOL-code: Relatief bestand lezen

       DATA DIVISION.
       FILE SECTION.
       FD persoon.
       01 gegevens PIC X(50).

       WORKING-STORAGE SECTION.
       77 persoonnummer PIC 99.
        88 stoppen      VALUE 0.

Zoals er in het vorige stukje werd gezegd moet je opletten met de lengte van de record. Als je de record hebt weggeschreven met een lengte van 50 tekens moet je die ook met die lengte weer lezen. Met de variabele persoonnummer gaan we de records lezen. Als persoonnummer 0 is wordt stoppen actief die komt van pas bij de lus dat we gaan gebruiken.

COBOL-code: Relatief bestand lezen

           DISPLAY "Geef nummer van de persoon(0 om te stoppen):"
           ACCEPT persoonnummer NO BEEP

           PERFORM UNTIL stoppen
               READ persoon
               DISPLAY "persoonnummer | gegevens"
               DISPLAY persoonnummer "              " gegevens
               DISPLAY " "
               DISPLAY "Geef nummer van de persoon(0 om te stoppen):"
               ACCEPT persoonnummer NO BEEP
           END-PERFORM

Om een record op te halen is het enige wat je moet doen een nummer zetten in persoonnummer er moet wel een record zijn met dat nummer. Vervolgens doe je gewoon READ en de gegevens worden opgehaald. Is persoonnummer 0 dan stopt de lus.

Fouten[bewerken]

De kans is natuurlijk heel groot dat er fouten zullen gebeuren wanneer je een nummer vraagt. De gebruiker kan het fout in typen of het record bestaat gewoonweg niet. Om te vermijden dat je aan raar foutbericht krijgt of het programma plotseling beëindigt kun je in COBOL een klein beveiliging inbouwen. Dit kost weinig moeite en het is best dat je het erbij zet.

COBOL-code: Foute sleutel

           PERFORM UNTIL stoppen
               READ persoonrel
                 INVALID KEY DISPLAY "U heeft een fout nummer gegeven."
                 DISPLAY " "

                 NOT INVALID KEY
                 DISPLAY "persoonnummer | gegevens"
                 DISPLAY persoonnummer "              " gegevensrel
                 DISPLAY " "
               END-READ
               DISPLAY "Geef nummer van de persoon(0 om te stoppen):"
               ACCEPT persoonnummer NO BEEP
           END-PERFORM

Dit gaat dus via INVALID KEY en NOT INVALID KEY. Achter INVALID KEY kun je dus een stukje programmacode schrijven voor het geval dat het nummer fout is. Achter NOT INVALID KEY kun je dus een stukje code schrijven voor als het wel juist is.

Record toevoegen[bewerken]

  Zie ook WRITE voor meer informatie.

Hier zullen we zien hoe je makkelijk een record kunt toevoegen aan een relatief bestand.

COBOL-code: Record toevoegen

       IDENTIFICATION DIVISION.
       PROGRAM-ID. relatief.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT persoon ASSIGN TO "persoonr.dat"
               ORGANIZATION RELATIVE
               ACCESS SEQUENTIAL
               RELATIVE KEY persoonnummer.

       DATA DIVISION.
       FILE SECTION.
       FD persoon.
       01 gegevens PIC X(50).

       WORKING-STORAGE SECTION.
       77 persoonnummer PIC 99.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN EXTEND persoon
           DISPLAY "Geef de gegevens van de persoon van de persoon:"
           ACCEPT gegevens NO BEEP

           WRITE gegevens
           DISPLAY "De nummer van de persoon is: " persoonnummer
           CLOSE persoon
           STOP RUN.

Een record toevoegen vraagt weinig programmeerwerk. OPEN EXTEND wilt zeggen dat je het bestand opent met de bedoeling om achteraan in het bestand iets toe te voegen. Dus je kunt alleen maar een record vanachter toevoegen niet meer niet minder. Je laat de gegevens inlezen en schrijft die in het bestand d.m.v. WRITE. Dan kun je nog als extra de relatieve sleutel laten zien. Dan kan de gebruiker later de gegevens nog terugvinden d.m.v. die sleutel.

Record herschrijven[bewerken]

  Zie ook REWRITE voor meer informatie.

Nu gaan we zien hoe je een record moet herschrijven.

COBOL-code: Record toevoegen

       IDENTIFICATION DIVISION.
       PROGRAM-ID. relatief.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT persoon ASSIGN TO "persoonr.dat"
               ORGANIZATION RELATIVE
               ACCESS RANDOM
               RELATIVE KEY persoonnummer.

       DATA DIVISION.
       FILE SECTION.
       FD persoon.
       01 gegevens PIC X(50).

       WORKING-STORAGE SECTION.
       77 persoonnummer PIC 99.
       77 aanpassen     PIC X.
        88 ja           VALUE "J", "j".

       PROCEDURE DIVISION.
       HOOFD.
           OPEN I-O persoon
           DISPLAY "Geef nummer van de persoon die je wil aanpassen:"
           ACCEPT persoonnummer NO BEEP

           READ persoon
           DISPLAY "persoonnummer | gegevens"
           DISPLAY persoonnummer "              " gegevens
           DISPLAY " "
           DISPLAY "Wilt u de gegevens aanpassen(j/n)"
           ACCEPT aanpassen NO BEEP
           IF ja
             THEN DISPLAY "geef de nieuwe gegevens"
             ACCEPT gegevens
             REWRITE gegevens
           END-IF
           CLOSE persoon
           STOP RUN.

OPEN I-O is nieuw, I-O is afgekort van INPUT-OUTPUT en betekent dus dat je het bestand zowel kunt lezen als schrijven. In dit programma vragen we eerst het nummer van de persoon op. Vervolgens tonen we die gegevens op het scherm en vragen we of deze gegevens moet worden aangepast. Je plaatst de nieuwe gegevens in de variabel gegevens en gebruikt REWRITE om ze weg te schrijven. Bij REWRITE kun je ook gebruik maken van INVALID KEY en NOT INVALID KEY.

Record verwijderen[bewerken]

  Zie ook DELETE voor meer informatie.

Het laatste dat we nog moeten zien is een record verwijderen.

COBOL-code: Record toevoegen

       IDENTIFICATION DIVISION.
       PROGRAM-ID. relatief.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT persoon ASSIGN TO "persoonr.dat"
               ORGANIZATION RELATIVE
               ACCESS RANDOM
               RELATIVE KEY persoonnummer.

       DATA DIVISION.
       FILE SECTION.
       FD persoon.
       01 gegevens PIC X(50).

       WORKING-STORAGE SECTION.
       77 persoonnummer PIC 99.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN I-O persoon
           DISPLAY "Geef nummer van de persoon die je wil verwijderen:"
           ACCEPT persoonnummer NO BEEP
           DELETE persoon
           STOP RUN.

Als je iets uit een relatief bestand wilt verwijderen moet je dit openen via INPUT-OUTPUT anders werkt het niet. Dit programma vraagt het nummer en verwijdert dan het record met dat nummer via DELETE. Bij DELETE kun je ook INVALID KEY en NOT INVALID KEY gebruiken.


3. Relatieve bestanden met hash



Relatieve bestanden kunnen via een sleutel makkelijk een record terugvinden. Dit kan via een cijfer (van 1 tot n). Maar een cijfer is niet altijd handig, en vaak weinig informatief. Een naam of een beschrijvend woord zouden makkelijker zijn. COBOL laat het gebruik van namen toe via een omweg: een hash-functie zet de naam om in een cijfer waarmee je makkelijk het record kunt terugvinden. Het grote nadeel van een relatief bestand met hash is dat je op voorhand moet weten hoeveel records je maximaal zult hebben. Als je eerst 10 records wou hebben en je maakt dat bestand aan, moet je wanneer je plotseling 20 records wilt opslaan een nieuw relatief bestand aanmaken.

Relatief bestand met hash aanmaken[bewerken]

Zoals een gewoon relatief bestand moeten we vertrekken vanuit een sequentieel bestand. We lezen dus eerst een sequentieel bestand in, en maken daarvan een relatief bestand met hash.

COBOL-code: Het sequentiële bestand.

Wikipedia   De vrije encyclopedie
Wiktionary  Vrij woordenboek met definities en uitleg
Wikimedia   Website over de projecten van Wikimedia
Wikiquote   Verzameling citaten
Wikibooks   Handleidingen en vrije boeken
Wikinews    Vrije nieuwsbron
Wikisource  Documenten vanuit publiek domein
Wikispecies Catalogus van alle soorten
Commons     Vrije mediabestanden

Dit bestand gaan we omzetten in een relatief bestand. Het bevat de namen van wiki's met hun omschrijvingen. De namen van de wiki's zullen we gebruiken als sleutel. In het relatief bestand zal zowel de naam als de omschrijving van de wiki staan. Hieronder is een voorbeeld van een programma dat dit voor ons zal doen.

COBOL-code: Het programma dat het relatief bestand zal aanmaken.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. Wiki.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT wikiseq ASSIGN TO "wikiseq.txt"
             ORGANIZATION LINE SEQUENTIAL
             FILE STATUS seqstatus.

           SELECT wikirel ASSIGN TO "wikirel.txt"
             ORGANIZATION RELATIVE
             ACCESS RANDOM
             RELATIVE KEY nummer
             FILE STATUS relstatus.

       DATA DIVISION.
       FILE SECTION.
       FD wikiseq.
       01 seqwiki.
        02 seqnaam PIC X(11).
        02 PIC X.
        02 seqomschr PIC X(50).
       
       FD wikirel.
       01 relwiki.
        02 relnaam PIC X(11).
        02 relomschr PIC X(50).

       WORKING-STORAGE SECTION.
       01 seqstatus PIC XX.
        88 eofseq VALUE '10'.
       01 relstatus PIC XX.
        88 eofrel VALUE '10'.
        88 slechtesleutel VALUE '23'.

       01 nummer PIC 99.
       01 wikinaam PIC X(11).
       01 wikinummer PIC 9(11).
       01 kleineletters PIC X(27) VALUE 'abcdefghijklmnopqrstuvwxyz '.
       01 hoofdletters PIC X(27) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '.
       01 cijfers PIC X(27) VALUE '012345678901234567890123456'.
       01 teller PIC 99.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN OUTPUT wikirel
           CLOSE wikirel
           OPEN INPUT wikiseq I-O wikirel
           READ wikiseq NEXT AT END CONTINUE END-READ
           PERFORM omzetten UNTIL eofseq
           CLOSE wikiseq wikirel
           STOP RUN.

       OMZETTEN.
           PERFORM zoeken
           IF slechtesleutel 
             THEN 
                  MOVE seqnaam TO relnaam
                  MOVE seqomschr TO relomschr
                  WRITE relwiki
           END-IF
           READ wikiseq NEXT AT END CONTINUE END-READ.

       ZOEKEN.
           PERFORM hash
           READ wikirel INVALID KEY CONTINUE END-READ
           PERFORM VARYING teller FROM 1 BY 1 UNTIL slechtesleutel
           OR seqnaam = relnaam OR teller > 9
             PERFORM botsing
             READ wikirel INVALID KEY CONTINUE END-READ
           END-PERFORM.

       HASH.
           MOVE seqnaam TO wikinaam
           INSPECT wikinaam CONVERTING kleineletters to hoofdletters
           INSPECT wikinaam CONVERTING hoofdletters TO cijfers
           DIVIDE wikinummer BY 9 GIVING wikinummer REMAINDER nummer
           ADD 1 TO nummer.

       BOTSING.
           ADD 1 TO nummer.
           IF nummer = 10
             MOVE 1 TO nummer
           END-IF.

Een relatief bestand aanmaken met hash kan zeer moeilijk zijn om te doen en te begrijpen. Nu gaan we stap voor stap voor stap uitleggen wat dit programma doet.

COBOL-code: De bestanden benaderen.

           SELECT wikiseq ASSIGN TO "wikiseq.txt"
             ORGANIZATION LINE SEQUENTIAL
             FILE STATUS seqstatus.

           SELECT wikirel ASSIGN TO "wikirel.txt"
             ORGANIZATION RELATIVE
             ACCESS RANDOM
             RELATIVE KEY nummer
             FILE STATUS relstatus.

Als u de twee vorige hoofdstukken hebt gelezen dan zal dit niet moeilijk zijn om te begrijpen. wikiseq is het bestand dat hier helemaal bovenaan werd beschreven en we zullen gebruiken om een relatieve bestand met hashfunctie aan te maken. wikirel zal natuurlijk dat bestand zijn, bij dit bestand is er wel iets waar je voor moet opletten. In het vorige hoofdstuk Relatieve bestanden zonder hash gebruikten we ACCESS SEQUENTIAL maar door de hash-functie moeten we dit bestand met een RANDOM benaderen, hier gaan we later nog op in.

COBOL-code: Hoofd.

       HOOFD.
           OPEN OUTPUT wikirel
           CLOSE wikirel
           OPEN INPUT wikiseq I-O wikirel
           READ wikiseq NEXT AT END CONTINUE END-READ
           PERFORM omzetten UNTIL eofseq

In het begin moeten we natuurlijk de bestanden openen, het relatief bestand wikirel moet als I-O(INPUT-OUTPUT) worden gelezen want er wordt in dit bestand zowel geschreven als gelezen. Waarom wordt ook later uitgelegd. Maar we moeten echter eerst een keer die relatief bestand openen als OUTPUT, dit zorgt ervoor dat het bestand wordt aangemaakt als het nog niet bestaat en voorkomt dat er fouten zijn als we het vervolgens openen met I-O. We lezen vervolgens het eerste lijntje in van het sequentiële bestand. Om vervolgens naar het deelprogramma omzetten te gaan als het op het einde van het sequentiële bestand is zal het deelprogramma stoppen.

Als we in omzetten zijn aangekomen, gaan we meteen naar het deelprogramma zoeken en van daaruit meteen naar de hash-functie.

COBOL-code: Hash-functie

       HASH.
           MOVE seqnaam TO wikinaam
           INSPECT wikinaam CONVERTING kleineletters to hoofdletters
           INSPECT wikinaam CONVERTING hoofdletters TO cijfers
           MOVE wikinaam TO wikinummer
           DIVIDE wikinummer BY 9 GIVING wikinummer REMAINDER nummer
           ADD 1 TO nummer.

Dit is waar alles om draait, dit klein stukje code zorgt ervoor dat je via een woord of een naam een record zult kunnen plaatsen of vinden. We slaan eerst de naam van de wiki op in een hulpveld. Met dit hulpveld zullen we de hash-functie gebruiken. Eerst zorgen we ervoor dat alles in hoofdletters staat via de INSPECT(zie Werken met tekst). Als dat gebeurd is moeten we alles omzetten in een cijfer; dit doen we ook via INSPECT. Wikinaam is nog steeds een alfanumeriek veld en hiermee kan je niet rekenen. Dit moeten we eerst in een numeriek veld overzetten. Het getal dat we nu hebben is 11 tekens lang, goed voor 100 miljard mogelijke combinaties. Dit is natuurlijk teveel van het goede we hebben maar 9 records die we willen opslaan. De oplossing is het getal delen door het aantal records dat we willen opslaan. De uitkomst ervan interesseert ons niet want dat is nog steeds meer dan 10 miljard. Wat ons wel interesseert is de restwaarde, dat zal een getal zijn van 0 tot 8. Dat zijn 9 verschillende combinaties. Maar aangezien COBOL niet zero-based is in vergelijking met bijvoorbeeld Java moeten we er één bij optellen. Dit geeft ons dan een getal van 1 tot 9 en slaan we op in het veld dat dient als RELATIVE KEY, in dit geval nummer. Vervolgens gaan we terug naar het deelprogramma zoeken.

Opmerking: Hoe je precies aan het eindgetal komt maakt eigenlijk niet uit zolang je maar aan een getal komt dat gebaseerd is op de naam of het woord en dat genoeg kans loopt om te verschillen met de getallen van andere namen of woorden.

COBOL-code: Zoeken.

       ZOEKEN.
           PERFORM hash
           READ wikirel INVALID KEY CONTINUE END-READ
           PERFORM VARYING teller FROM 1 BY 1 UNTIL slechtesleutel
           OR seqnaam = relnaam OR teller > 9
             PERFORM botsing
             READ wikirel INVALID KEY CONTINUE END-READ
           END-PERFORM.

De hash functie is juist gebeurd. We hebben dus een sleutel en we lezen vervolgens het relatief bestand. Dit is meteen de reden waarom we het geopend hebben als I-O: we moeten het bestand ook lezen omdat we moeten zien of er niet al een record op die plaats is. Als er geen record is op die plaats dan krijgen we een INVALID KEY, hier slechtesleutel genaamd. INVALID KEY betekent hier ironisch genoeg dat het goed is want op de plaats van onze sleutel is er geen record dus kunnen we daar een record wegschrijven. Maar wat als er wel een record is? Hiervoor zijn drie mogelijke oorzaken: ofwel heeft toevallig een ander record dezelfde sleutel gekregen van de hashfunctie of hebben we het record al een keer weggeschreven of we hebben al 9 records weggeschreven. Aan de twee laatste kunnen we niet veel doen als het record al weggeschreven is maakt het niet veel uit en als we al 9 records hebben weggeschreven moeten we het programma aanpassen zodat we toch meer dan 9 records kunnen gebruiken. Als er toevallig een ander record dezelfde sleutel heeft gekregen noemen we dat een botsing of collision. Dit is niet erg en het gebeurt vrijwel altijd. Het simpelste wat we kunnen doen om het op te lossen is gewoon één bijtellen bij de sleutel en het opnieuw te proberen, dit gebeurt in het deelprogramma botsing. Het is bijna gedaan want nu gaan we al terug naar het deelprogramma omzetten.

COBOL-code: Omzetten.

       OMZETTEN.
           PERFORM zoeken
           IF slechtesleutel 
             THEN 
                  MOVE seqnaam TO relnaam
                  MOVE seqomschr TO relomschr
                  WRITE relwiki
           END-IF
           READ wikiseq NEXT AT END CONTINUE END-READ.

Onthoud INVALID KEY betekende in dit geval goed en daardoor is het veld slechtesleutel geactiveerd. Vervolgens gebeurt net hetzelfde als bij een gewoon relatief bestand. Schrijf alles weg en lees het volgende record van het sequentiële bestand. Als alle records zijn gelezen sluit de twee bestanden en het programma heeft zijn werk gedaan.

Relatief bestand met hash lezen[bewerken]

Als je een relatief bestand met hash aanmaken onder de knie hebt moet dit niet zo moeilijk meer zijn. Jammer genoeg als je zeker wilt weten of je zo'n bestand perfect hebt kunnen maken moet je eerst ze ook kunnen lezen. Dit volgend programma leest dat bestand van het vorige stukje in. De gebruiker geeft de naam van de wiki en het programma geeft zijn omschrijving.

COBOL-code: Een relatief bestand met hash lezen.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. Wiki.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

           SELECT wikirel ASSIGN TO "wikirel.txt"
             ORGANIZATION RELATIVE
             ACCESS RANDOM
             RELATIVE KEY nummer.

       DATA DIVISION.
       FILE SECTION.  
       FD wikirel.
       01 relwiki.
        02 relnaam PIC X(11).
        02 relomschr PIC X(50).

       WORKING-STORAGE SECTION.
       01 nummer PIC 99.
       01 wikinaam PIC X(11).
       01 hulp PIC x(11).
       01 wikinummer PIC 9(11).
       01 kleineletters PIC X(27) VALUE 'abcdefghijklmnopqrstuvwxyz '.
       01 hoofdletters PIC X(27) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '.
       01 cijfers PIC X(27) VALUE '012345678901234567890123456'.
       01 teller PIC 99.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN INPUT wikirel
           ACCEPT wikinaam NO BEEP
           PERFORM zoeken
           CLOSE wikirel
           STOP RUN.

       ZOEKEN.
           PERFORM hash
           PERFORM varying teller FROM 1 BY 1 UNTIL teller > 9
             READ wikirel END-READ
             IF relnaam = wikinaam
               THEN
                 DISPLAY relomschr
                 MOVE 10 TO teller
               ELSE 
                 PERFORM botsing
             END-IF
           END-PERFORM.

       HASH.
           MOVE wikinaam TO hulp
           INSPECT hulp CONVERTING kleineletters to hoofdletters
           INSPECT hulp CONVERTING hoofdletters TO cijfers
           MOVE hulp TO wikinummer
           DIVIDE wikinummer BY 9 GIVING wikinummer REMAINDER nummer
           ADD 1 TO nummer.

       BOTSING.
           ADD 1 TO nummer.
           IF nummer = 10
             MOVE 1 TO nummer
           END-IF.

De hash-functie en botsingzijn in dit programma nogsteeds hetzelfde, dus het enige waar je moet voor opletten is de hoofd en zoeken.

COBOL-code: hoofd.

       HOOFD.
           OPEN INPUT wikirel
           ACCEPT wikinaam NO BEEP
           PERFORM zoeken
           CLOSE wikirel
           STOP RUN.

De hoofd is niet echt moeilijk. Je moet het relatief gewoon open als input en vervolgens lees je de naam van de wiki in waarvan je de omschrijving wilt hebben. Vervolgens voer je zoeken uit.

COBOL-code: zoeken.

       ZOEKEN.
           PERFORM hash
           PERFORM varying teller FROM 1 BY 1 UNTIL teller > 9
             READ wikirel END-READ
             IF relnaam = wikinaam
               THEN
                 DISPLAY relomschr
                 MOVE 10 TO teller
               ELSE 
                 PERFORM botsing
             END-IF
           END-PERFORM.

Zoeken is het enige waar je misschien nog moet opletten. Eers voor je natuurlijk de hash-functie uit en die geeft dan een sleutel. Vervolgens start je met een lus die maximaal het aantal records dat er in het bestand zit zal draaien. Je voert een READ uit met de sleutel die je hebt van de hash-functie. Nu moeten we eerst controleren of het wel het juist record is. Dit doen we door de naam da we hebben gekregen van de gebruiker te verglijken met dat van de record. Als het juist is toont dit programma gewoon de omschrijving van de wiki. Als het fout is moet botsing worden uitgevoerd tot het record is gevonden.

Record herschrijven[bewerken]

Een record herschrijven is niet moeilijk en je kunt de code van het vorige stukje gebruiken en gewoon een beetje aanpassen.

COBOL-code: Record herschrijven.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. Wiki.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

           SELECT wikirel ASSIGN TO "wikirel.txt"
             ORGANIZATION RELATIVE
             ACCESS RANDOM
             RELATIVE KEY nummer.

       DATA DIVISION.
       FILE SECTION.  
       FD wikirel.
       01 relwiki.
        02 relnaam PIC X(11).
        02 relomschr PIC X(50).

       WORKING-STORAGE SECTION.
       01 nummer PIC 99.
       01 wikinaam PIC X(11).
       01 hulp PIC x(11).
       01 wikinummer PIC 9(11).
       01 kleineletters PIC X(27) VALUE 'abcdefghijklmnopqrstuvwxyz '.
       01 hoofdletters PIC X(27) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '.
       01 cijfers PIC X(27) VALUE '012345678901234567890123456'.
       01 teller PIC 99.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN I-O wikirel
           DISPLAY "Geef de naam van de wiki die je wilt aanpassen:"
           ACCEPT wikinaam NO BEEP
           PERFORM zoeken
           CLOSE wikirel
           STOP RUN.

       ZOEKEN.
           PERFORM hash
           PERFORM varying teller FROM 1 BY 1 UNTIL teller > 9
             READ wikirel END-READ
             IF relnaam = wikinaam
               THEN
                 DISPLAY "Het originele inhoud: " relomschr
                 DISPLAY "Geef de nieuwe inhoud: "
                 ACCEPT relomschr NO BEEP
                 REWRITE relwiki END-REWRITE
                 MOVE 10 TO teller
               ELSE 
                 PERFORM botsing
             END-IF
           END-PERFORM.

       HASH.
           MOVE wikinaam TO hulp
           INSPECT hulp CONVERTING kleineletters to hoofdletters
           INSPECT hulp CONVERTING hoofdletters TO cijfers
           MOVE hulp TO wikinummer
           DIVIDE wikinummer BY 9 GIVING wikinummer REMAINDER nummer
           ADD 1 TO nummer.

       BOTSING.
           ADD 1 TO nummer.
           IF nummer = 10
             MOVE 1 TO nummer
           END-IF.

Niet zoveel verschil dus. Er zijn slechts twee zaken die echt anders zijn. Ten eerste hoe je het bestand moeten openen. Net zoals een gewoon relatief bestand moet je dit openen met I-O(INPUT-OUTPUT). Vervolgens doe je nadat je het record hebt gevonden die je wilt aanpassen een REWRITE net zoals een gewoon relatief bestand. Hieronder is er een schermafdruk van dit programma.

Geef de naam van de wiki die je wilt aanpassen:
Wikipedia
Het originele inhoud: De vrije encyclopedie
Geef de nieuwe inhoud:
VRIJE ENCYCLOPEDIE

Als je dan opnieuw wikipedia opzoekt zal je zien dat er "VRIJ ENCYCLOPEDIE" staat.

Record verwijderen[bewerken]

Dit volgende programma is gebaseerd op het vorige maar in de plaats van een record te herschrijven wordt die gedelete.

COBOL-code: Record verwijderen.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. RecordVerwijderen.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT wikirel ASSIGN TO "wikirel.txt"
             ORGANIZATION RELATIVE
             ACCESS RANDOM
             RELATIVE KEY nummer.

       DATA DIVISION.
       FILE SECTION.  
       FD wikirel.
       01 relwiki.
        02 relnaam PIC X(11).
        02 relomschr PIC X(50).

       WORKING-STORAGE SECTION.
       01 nummer PIC 99.
       01 wikinaam PIC X(11).
       01 hulp PIC x(11).
       01 wikinummer PIC 9(11).
       01 kleineletters PIC X(27) VALUE 'abcdefghijklmnopqrstuvwxyz '.
       01 hoofdletters PIC X(27) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '.
       01 cijfers PIC X(27) VALUE '012345678901234567890123456'.
       01 teller PIC 99.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN I-O wikirel
           DISPLAY "Geef de naam van de wiki die je wilt verwijderen:"
           ACCEPT wikinaam NO BEEP
           PERFORM zoeken
           CLOSE wikirel
           STOP RUN.

       ZOEKEN.
           PERFORM hash
           PERFORM varying teller FROM 1 BY 1 UNTIL teller > 9
             READ wikirel END-READ
             IF relnaam = wikinaam
               THEN
                 DELETE wikirel
                 DISPLAY "Record verwijderd"
                 MOVE 10 TO teller
               ELSE 
                 PERFORM botsing
             END-IF
           END-PERFORM.

       HASH.
           MOVE wikinaam TO hulp
           INSPECT hulp CONVERTING kleineletters to hoofdletters
           INSPECT hulp CONVERTING hoofdletters TO cijfers
           MOVE hulp TO wikinummer
           DIVIDE wikinummer BY 9 GIVING wikinummer REMAINDER nummer
           ADD 1 TO nummer.

       BOTSING.
           ADD 1 TO nummer.
           IF nummer = 10
             MOVE 1 TO nummer
           END-IF.

Niet zo veel verschil met het vorige. DELETE in de plaats van REWRITE en natuurlijk altijd openen met I-O(INPUT-OUTPUT). Als je een record wilt lezen die je hebt gedelete geeft hij een foutmelding.


4. Index-sequentiële bestanden


Programmeren in COBOL/Bestandsorganisatie/Index-sequentiële bestanden


Informatie afkomstig van https://nl.wikibooks.org Wikibooks NL.
Wikibooks NL is onderdeel van de wikimediafoundation.