[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 674.   Divisione «ENVIRONMENT DIVISION»

La divisione ENVIRONMENT DIVISION costituisce la seconda parte di un programma COBOL. La divisione si compone di due sezioni: CONFIGURATION SECTION e INPUT-OUTPUT SECTION.

La sezione CONFIGURATION SECTION serve per indicare delle informazioni relative all'elaboratore usato per la compilazione del programma sorgente e a quello nel quale deve essere eseguito il programma, una volta compilato; inoltre, questa sezione permette di stabilire delle sostituzioni, come nel caso della virgola al posto del punto per separare la parte intera di un numero dalla parte decimale.

La sezione INPUT-OUTPUT SECTION serve per associare i file usati dal programma con le unità fisiche relative, a indicare le caratteristiche di tali file e a stabilire altri aspetti dello scambio di dati.

674.1   Struttura

La struttura della divisione ENVIRONMENT DIVISION è sintetizzabile nello schema sintattico seguente:

   ENVIRONMENT DIVISION.
.--¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯                   --.
|  CONFIGURATION SECTION.                   |
|  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯                    |
| [SOURCE-COMPUTER. source-computer-entry]. |
|  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯                          |
| [OBJECT-COMPUTER. object-computer-entry]. |
|  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯                          |
| [SPECIAL-NAMES. special-names-entry].     |
`--¯¯¯¯¯¯¯¯¯¯¯¯¯                          --'
.--                                           --.
|  INPUT-OUTPUT SECTION.                        |
|  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯                         |
|  FILE-CONTROL. file-control-entry...          |
|  ¯¯¯¯¯¯¯¯¯¯¯¯                                 |
| [I-O-CONTROL. input-output-control-entry...]. |
`--¯¯¯¯¯¯¯¯¯¯¯                                --'

674.2   Sezione «CONFIGURATION SECTION»

La sezione CONFIGURATION SECTION contiene le informazioni sul sistema usato per la compilazione del programma (nel paragrafo SOURCE-COMPUTER), il sistema nel quale il programma deve essere eseguito (nel paragrafo OBJECT-COMPUTER) e il paragrafo SPECIAL-NAMES che consente di effettuare alcune sostituzioni a dei valori che altrimenti resterebbero al loro stato predefinito.

 CONFIGURATION SECTION.
 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
[SOURCE-COMPUTER. source-computer-entry].
 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
[OBJECT-COMPUTER. object-computer-entry].
 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
[SPECIAL-NAMES. special-names-entry].
 ¯¯¯¯¯¯¯¯¯¯¯¯¯

674.2.1   Paragrafo «SOURCE-COMPUTER»

Il paragrafo SOURCE-COMPUTER identifica l'elaboratore presso il quale si intende compilare il programma. Si utilizza secondo lo schema sintattico seguente:

SOURCE-COMPUTER. computer-name [WITH DEBUGGING MODE].
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯                      ¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Al posto della metavariabile computer-name deve essere indicata una parola COBOL, che serve solamente a titolo informativo nel sorgente. Se si specifica l'opzione DEBUGGING MODE si richiede al compilatore di prendere in considerazione, nel sorgente, tutte le righe annotate con la lettera D nella settima colonna e le istruzioni USE FOR DEBUGGING, che altrimenti verrebbero semplicemente ignorate.

674.2.2   Paragrafo «OBJECT-COMPUTER»

Il paragrafo OBJECT COMPUTER identifica l'elaboratore presso il quale deve essere utilizzato il programma, una volta compilato. Lo schema sintattico per l'utilizzo di questo paragrafo è quello seguente:

OBJECT-COMPUTER. computer-name... .
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Il nome dell'elaboratore (computer name) deve essere una parola COBOL e ha un significato puramente informativo. Alla fine dell'indicazione dell'ultimo nome, deve apparire un punto fermo.

674.2.3   Paragrafo «SPECIAL-NAMES»

Il paragrafo SPECIAL-NAMES serve ad associare un valore a dei nomi prestabiliti, quando si vuole che la funzione loro associata sia diversa da quella predefinita, oppure ad attribuire un «nome mnemonico» a un nome usato dal compilatore, che però non fa parte dello standard. Le dichiarazioni che possono apparire in questo paragrafo dipendono molto dalle caratteristiche del compilatore; quello che si vede nello schema sintattico seguente è il minimo che dovrebbe essere disponibile nella maggior parte dei casi:

SPECIAL-NAMES.
¯¯¯¯¯¯¯¯¯¯¯¯¯
    implementor-name IS mnemonic-name
                     ¯¯
    [CURRENCY SIGN IS literal]
     ¯¯¯¯¯¯¯¯      ¯¯
    [DECIMAL-POINT IS COMMA].
     ¯¯¯¯¯¯¯¯¯¯¯¯¯    ¯¯¯¯¯

Si utilizza la dichiarazione CURRENTY SIGN IS per fissare il simbolo predefinito da usare come segno di valuta; si usa la dichiarazione DECIMAL-POINT IS COMMA per rappresentare i valori numerici secondo la forma europea, dove la virgola indica la separazione tra la parte intera e quella decimale.

Il segno di valuta può essere costituito da un solo carattere e sono molto pochi i simboli che si possono usare. Per la precisione, sono esclusi tutti i simboli che invece possono essere usati nei modelli di definizione delle variabili oltre a quelli che si usano come delimitatori. In linea di massima sono da escludere: tutte le cifre numeriche (da 0 a 9); lo spazio; le lettere alfabetiche A, B, C, D, J, L, N, P, R, S, V, X, Z; i caratteri speciali *, +, -, ,, ., ;, %, (, ), ", ?.

Si osservi che anche nel modello di definizione di una variabile (PICTURE), quando si usa la dichiarazione DECIMAL-POINT IS COMMA, il punto e la virgola si scambiano i ruoli.

L'esempio seguente mostra un pezzo di programma in cui si vede l'uso di queste opzioni. Per la precisione, si assegna la lettera «E» per rappresentare la valuta:

000000 ENVIRONMENT DIVISION.
000000 CONFIGURATION SECTION.
000000 SPECIAL-NAMES. DECIMAL-POINT IS COMMA
000000                CURRENCY SIGN IS "E".

L'attribuzione di un nome mnemonico a una parola non standard che però fa parte delle funzionalità specifiche del compilatore utilizzato, consente di limitare a questa sezione le modifiche per l'adattamento del programma a un compilatore che ha funzioni simili, ma descritte da parole diverse. Nell'esempio seguente, compilabile con OpenCOBOL, si sostituisce la parola CONSOLE con STANDARD-INPUT, per identificare la fonte dei dati in ingresso per l'istruzione ACCEPT:

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID.   TEST-ACCEPT.
000300 AUTHOR.       DANIELE GIACOMINI.
000400 DATE-WRITTEN. 2005-02-27.
000500*
000600 ENVIRONMENT DIVISION.
000700 CONFIGURATION SECTION.
000800 SOURCE-COMPUTER.
000900     OPENCOBOL.
001000 SPECIAL-NAMES.
001100     CONSOLE IS STANDARD-INPUT.
001200*
001300 DATA DIVISION.
001400*
001500 WORKING-STORAGE SECTION.
001600 77  MESSAGGIO            PIC X(30).
001700*
001800 PROCEDURE DIVISION.
001900*
002000 MAIN.
002100     DISPLAY "INSERISCI IL MESSAGGIO".
002200     ACCEPT MESSAGGIO FROM STANDARD-INPUT.
002300     DISPLAY "HAI INSERITO: ", MESSAGGIO.
002400*
002500     STOP RUN.
002600*

Nell'esempio appena mostrato sono evidenziate le righe più importanti per la comprensione del meccanismo; si può comprendere che l'istruzione ACCEPT avrebbe potuto essere scritta semplicemente così:

002200     ACCEPT MESSAGGIO FROM CONSOLE.

Tuttavia, avendo utilizzato il nome mnemonico STANDARD-INPUT, se con un altro compilatore la console fosse identificata dalla sigla SPO (Supervisory printer output, come avveniva nel COBOL CMS (Computer management system della Burroughs negli anni 1980), basterebbe modificare la dichiarazione iniziale:

001000 SPECIAL-NAMES.
001100     SPO IS STANDARD-INPUT.

Per chiarezza, è il caso di sottolineare che STANDARD-INPUT ha valore per il compilatore solo in quanto viene dichiarato come nome mnemonico, dal momento che il linguaggio, nella sua veste ufficiale, non prevede la gestione dei flussi standard dei sistemi Unix.

674.3   Sezione «INPUT-OUTPUT SECTION»

La sezione INPUT-OUTPUT SECTION si suddivide in due paragrafi: FILE-CONTROL e I-O-CONTROL. Il paragrafo FILE-CONTROL specifica l'organizzazione e l'accesso dei file che vengono usati dal programma e le informazioni correlate a tali file; il paragrafo I-O-CONTROL serve a specificare informazioni aggiuntive sui file già dichiarati nell'altro paragrafo.

 INPUT-OUTPUT SECTION.
 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
 FILE-CONTROL. file-control-entry...
 ¯¯¯¯¯¯¯¯¯¯¯¯
[I-O-CONTROL. input-output-control-entry...].
 ¯¯¯¯¯¯¯¯¯¯¯

674.3.1   Paragrafo «FILE-CONTROL»

Il paragrafo FILE-CONTROL serve a dichiarare i file utilizzati dal programma e a definire alcune loro caratteristiche. Tutti i file dichiarati nel paragrafo FILE-CONTROL devono essere descritti nella divisione DATA DIVISION; nello stesso modo, tutti i file descritti nella divisione DATA DIVISION, devono essere dichiarati nel paragrafo FILE-CONTROL.

Il linguaggio COBOL prevede una gestione dei file molto sofisticata, anche se non è detto che i compilatori mettano a disposizione sempre tutte le funzionalità standard. Si distinguono generalmente i tipi, in base alla loro «organizzazione», come sintetizzato nella tabella successiva.

Per il linguaggio COBOL i file sono sempre composti da record, pertanto l'accesso a un file si riferisce sempre a dei record.

Tabella 674.11. Classificazione dei file in base all'organizzazione.

Organizzazione Descrizione
sequenziale Il file sequenziale consente un accesso ai record in modo seriale, dal primo all'ultimo. Generalmente, si dichiara un accesso sequenziale ai file quando l'unità di memorizzazione nella quale sono memorizzati è per sua natura sequenziale, come per i nastri magnetici.
relativa (relative) Si tratta di un file ad accesso diretto, dove i record si possono raggiungere specificandone il numero, a partire da uno, avendo anche la possibilità di richiedere qualche spostamento relativo rispetto al record attuale.
a indice Si tratta di un file associato a un indice dei record. Attraverso l'indice è possibile raggiungere direttamente i record associati, senza bisogno di eseguire delle scansioni di ricerca.

L'organizzazione del file definisce le potenzialità di accesso, ma in generale sono disponibili diverse varianti nel modo particolare di accedere ai record.

Il paragrafo FILE CONTROL si articola in dichiarazioni SELECT, una per ogni file, secondo lo schema sintattico sintetico seguente:

FILE-CONTROL.
¯¯¯¯¯¯¯¯¯¯¯¯
    SELECT file-name ASSIGN TO hardware-name [altre-opzioni].
    ¯¯¯¯¯¯           ¯¯¯¯¯¯
    ...

Il modo in cui l'istruzione SELECT si articola, dipende dall'organizzazione del file e dal metodo di accesso specifico che si vuole attuare sullo stesso. Nella logica originale del linguaggio, in questa fase non viene ancora indicato il nome del file reale, secondo il sistema operativo, perché generalmente per questa informazione si agisce nella divisione DATA DIVISION; tuttavia, spesso il compilatore permette, o richiede, di specificare il nome del file reale proprio nell'istruzione SELECT.

674.3.2   File fisici e file «logici»

L'organizzazione di un file è una caratteristica immutabile, che stabilisce, oltre che le potenzialità di accesso, anche la sua forma fisica «reale», ovvero quella che viene gestita attraverso l'astrazione del sistema operativo.

L'organizzazione sequenziale è quella più semplice, dove normalmente i record logici del linguaggio corrispondono esattamente al contenuto del file fisico che li contiene.

L'organizzazione relativa richiede la capacità di abbinare delle informazioni ai record logici, per esempio per poter annotare che un record è stato cancellato. Per fare questo, il compilatore può inserire tutte le informazioni necessarie in un file solo, oppure può avvalersi di due file reali: uno per i dati, l'altro per le informazioni sui record.

L'organizzazione a indice richiede tutte le funzionalità di quella relativa, con l'aggiunta di poter gestire l'accesso in base a una o più chiavi. Nei compilatori COBOL attuali, è molto probabile che tutte le informazioni necessarie vengano gestite in un file fisico soltanto, ma originariamente era frequente l'uso di un file per i dati e di altri file per le chiavi (uno per ogni chiave).

In base a questa premessa, si deve intendere che un file che viene creato con una certa organizzazione, può essere usato solo con quella; inoltre, si può contare sul fatto che un file creato con un programma realizzato attraverso un certo compilatore COBOL, non può essere utilizzato con un programma generato con un altro.

Di fronte a questo problema di compatibilità dei dati, i file organizzati in modo sequenziale sono sempre l'unica garanzia per un trasferimento dei dati. D'altra parte, negli anni in cui il linguaggio COBOL aveva il suo massimo splendore, i nastri magnetici rappresentavano l'unità di memorizzazione «standard» tra le varie architetture proprietarie.

674.3.3   Istruzione «SELECT» per i file sequenziali

Lo schema sintattico semplificato per l'istruzione SELECT, da usare nel paragrafo FILE-CONTROL, per dichiarare un file sequenziale è quello che si può vedere nella figura successiva:

                            /                   \
                            |   hardware-name   |
SELECT file-name ASSIGN TO  <                   >
¯¯¯¯¯¯           ¯¯¯¯¯¯     | literal-file-name |
                            \                   /
    .--               .--   --. --.
    |                 | AREA  |   |
    | RESERVE integer |       |   |
    | ¯¯¯¯¯¯¯         | AREAS |   |
    `--               `--   --' --'

    [ ORGANIZATION IS [LINE] SEQUENTIAL ]
      ¯¯¯¯¯¯¯¯¯¯¯¯     ¯¯¯¯  ¯¯¯¯¯¯¯¯¯¯
    [ ACCESS MODE IS SEQUENTIAL ]
      ¯¯¯¯¯¯         ¯¯¯¯¯¯¯¯¯¯
    [ FILE STATUS IS data-name ].
           ¯¯¯¯¯¯

Il file sequenziale può essere letto o scritto soltanto in modo sequenziale, a partire dall'inizio. Se l'unità di memorizzazione che lo contiene è sequenziale per sua natura, come avviene per un nastro o un lettore di schede perforate, si può avere solo una fase di lettura o una fase di scrittura, senza la possibilità di mescolare le due operazioni, mentre se si dispone di un'unità di memorizzazione ad accesso diretto, come nel caso di un disco, si può leggere e poi sovrascrivere lo stesso record.

Nello schema sintattico, la metavariabile file-name deve essere sostituita con il nome che si vuole attribuire al file nell'ambito del programma (non si tratta del nome che questo ha eventualmente per il sistema operativo). La metavariabile hardware-name va sostituita con un nome che serve a identificare l'unità di memorizzazione che contiene il file; questo nome dipende dal compilatore ma generalmente si mette DISK per indicare un file su disco. Altri nomi per la metavariabile hardware-name potrebbero essere: TAPE, PRINTER, PUNCH, READER (gli ultimi due sarebbero un perforatore e un lettore di schede).

Il linguaggio COBOL è fatto per poter essere adattato a sistemi operativi molto diversi. In un sistema Unix, l'accesso alle unità di memorizzazione avviene attraverso dei file di dispositivo, pertanto, a seconda del compilatore, potrebbe anche essere superfluo dichiarare il tipo di unità di memorizzazione in questo modo, anche se in passato il linguaggio obbligava a farlo. Proprio per questo motivo, ci sono compilatori che, al posto di indicare il tipo di unità fisica attraverso un nome prestabilito, richiedono di mettere subito il percorso del file a cui si vuole fare riferimento, nonostante il linguaggio preveda per questo una dichiarazione separata nella divisione DATA DIVISION. In questo senso, nello schema sintattico appare la possibilità di indicare una stringa alfanumerica con il percorso del file (literal-file-name).

Nella dichiarazione RESERVE integer, la metavariabile integer rappresenta un numero intero di record da usare come memoria tampone. Se non si usa questa dichiarazione che, come si vede dallo schema sintattico, è facoltativa, viene usata la dimensione predefinita.

La dichiarazione ORGANIZATION IS SEQUENTIAL è facoltativa e sottintesa; tuttavia va osservato il significato che assume quando si aggiunge la parola LINE. In generale, il linguaggio COBOL considera i file come composti da record di dimensione uniforme. Quando però si vuole lavorare con i file di testo, le righe di questi file sono suddivise in base alla presenza del codice di interruzione di riga (che può cambiare da un sistema operativo all'altro). Volendo considerare in COBOL le righe di un file di testo pari a dei record di dimensione variabile, occorre aggiungere l'opzione LINE, così da chiarire che si tratta sì di un'organizzazione sequenziale, ma di un file suddiviso in «righe».

La dichiarazione ACCESS MODE IS SEQUENTIAL è facoltativa, perché l'accesso a un file organizzato in modo sequenziale può essere solo sequenziale.

La dichiarazione FILE STATUS IS data-name consente di indicare una variabile (da specificare nella sezione WORKING-STORAGE SECTION della divisione DATA DIVISION) da usare eventualmente per conoscere lo stato dell'ultima operazione svolta sul file. Questa variabile deve poter rappresentare un valore di due caratteri (il modello di definizione della variabile deve essere XX) e quando contiene il valore zero indica che l'ultima operazione è stata eseguita con successo (si vedano le tabelle 674.28 e 674.29, che appaiono alla fine del capitolo).

Il punto fermo che conclude l'istruzione SELECT appare una volta sola, alla fine; tutta l'istruzione deve risiedere nell'area B.

Viene mostrato un esempio completo di un programma COBOL che legge un file sequenziale:

Listato 674.14. Programma elementare che legge un file sequenziale.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID.   ESEMPIO-SEQUENZIALE.
000300 AUTHOR.       DANIELE GIACOMINI.
000400 INSTALLATION. NANOLINUX IV,
000500               TINYCOBOL 0.61.
000600 DATE-WRITTEN. 2005-02-16.
000700 ENVIRONMENT DIVISION.
000800 INPUT-OUTPUT SECTION.
000900*
001000 FILE-CONTROL.
001100     SELECT FILE-NAME ASSIGN TO DISK
001200                      ORGANIZATION IS SEQUENTIAL
001300                      ACCESS MODE IS SEQUENTIAL
001400                      FILE STATUS IS DATA-NAME.
001500*
001600 DATA DIVISION.
001700 FILE SECTION.
001800 FD  FILE-NAME
001900     LABEL RECORD IS STANDARD
002000     VALUE OF FILE-ID IS "input.seq".
002100 01  RECORD-NAME  PIC X(20).
002200 WORKING-STORAGE SECTION.
002300 01  DATA-NAME    PIC XX.
002400 PROCEDURE DIVISION.
002500 MAIN.
002600     OPEN INPUT  FILE-NAME.
002700     DISPLAY "FILE STATUS: ", DATA-NAME.
002800     PERFORM READ-FILE UNTIL DATA-NAME NOT = ZERO.
002900     CLOSE FILE-NAME.
003000     STOP RUN.
003100 READ-FILE.
003200     READ FILE-NAME.
003300     DISPLAY "FILE STATUS: " DATA-NAME, " RECORD: ", RECORD-NAME.

Il file indicato come FILE-NAME è associato in pratica al file input.seq. Si può supporre che questo file abbia il contenuto seguente, senza alcun codice di interruzione di riga:

aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbccccccccccccccccccccdddddddddddddddddddd

Eseguendo il programma dell'esempio si potrebbe ottenere il testo seguente attraverso lo schermo:

FILE STATUS: 00
FILE STATUS: 00 RECORD: aaaaaaaaaaaaaaaaaaaa
FILE STATUS: 00 RECORD: bbbbbbbbbbbbbbbbbbbb
FILE STATUS: 00 RECORD: cccccccccccccccccccc
FILE STATUS: 00 RECORD: dddddddddddddddddddd
FILE STATUS: 10 RECORD: dddddddddddddddddddd

674.3.4   Istruzione «SELECT» per i file relativi

Lo schema sintattico semplificato per l'istruzione SELECT, da usare nel paragrafo FILE-CONTROL, per dichiarare un file organizzato in modo «relativo» è quello che si può vedere nella figura successiva:

                            /                   \
                            |       DISK        |
SELECT file-name ASSIGN TO  <       ¯¯¯¯        >
¯¯¯¯¯¯           ¯¯¯¯¯¯     | literal-file-name |
                            \                   /

    .--               .--   --. --.
    |                 | AREA  |   |
    | RESERVE integer |       |   |
    | ¯¯¯¯¯¯¯         | AREAS |   |
    `--               `--   --' --'

    [ ORGANIZATION IS ] RELATIVE
      ¯¯¯¯¯¯¯¯¯¯¯¯      ¯¯¯¯¯¯¯¯
    .--               /   SEQUENTIAL                               \ --.
    |                 |   ¯¯¯¯¯¯¯¯¯¯                               |   |
    |                 |  /         \                               |   |
    | ACCESS MODE IS  <  | RANDOM  |                               >   |
    | ¯¯¯¯¯¯          |  < ¯¯¯¯¯¯  >  RELATIVE KEY IS data-name-1  |   |
    |                 |  | DYNAMIC |  ¯¯¯¯¯¯¯¯                     |   |
    `--               \  \ ¯¯¯¯¯¯¯ /                               / --'

    [ FILE STATUS IS data-name-2 ].
           ¯¯¯¯¯¯

Il file organizzato in modo relativo può essere utilizzato secondo un accesso sequenziale, oppure facendo riferimento ai record per numero, considerando che il primo ha proprio il numero uno. Quando si individuano i record per numero, si distinguono due modalità di accesso: diretto (RANDOM) e dinamico (DYNAMIC). L'accesso diretto richiede che per ogni operazione l'indicazione del numero del record a cui si vuole fare riferimento, mentre con l'accesso dinamico è anche possibile eseguire delle operazioni di lettura sequenziali (READ NEXT).

L'organizzazione relativa, oltre alle operazioni di lettura e scrittura, prevede la cancellazione dei record, che comunque possono essere rimpiazzati successivamente attraverso un'operazione di scrittura. Si osservi comunque che un record che risulta essere stato cancellato, non può essere letto.

Osservando lo schema sintattico si può intuire che la prima parte dell'istruzione SELECT funzioni nello stesso modo di un file organizzato sequenzialmente; la differenza più importante riguarda la definizione del tipo di unità di memorizzazione che, date le caratteristiche dei file organizzati in modo relativo, deve consentire un accesso diretto ai dati.

La dichiarazione RESERVE integer si usa nello stesso modo del file organizzato sequenzialmente.

L'indicazione dell'organizzazione, attraverso la dichiarazione ORGANIZATION IS RELATIVE è obbligatoria, anche se probabilmente è sufficiente scrivere soltanto RELATIVE.

Se non viene specificata la dichiarazione ACCESS MODE, si intende che l'accesso debba avvenire in modo sequenziale, altrimenti vale quanto indicato espressamente. Se l'accesso richiesto è diretto o dinamico, è necessario indicare quale variabile usare per specificare il numero del record, nella posizione occupata nello schema sintattico dalla metavariabile data-name-1 (da specificare ulteriormente nella sezione WORKING-STORAGE SECTION della divisione DATA DIVISION).

La dichiarazione FILE STATUS IS data-name-2 funziona nello stesso modo descritto a proposito dei file organizzati in modo sequenziale.

Il punto fermo che conclude l'istruzione SELECT appare una volta sola, alla fine; tutta l'istruzione deve risiedere nell'area B.

Viene mostrato un esempio completo di un programma COBOL che legge un file relativo, ad accesso diretto, scandendo sequenzialmente il numero del record:

Listato 674.18. Programma elementare che legge un file relativo, ad accesso diretto.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID.   ESEMPIO-RELATIVO-DIRETTO.
000300 AUTHOR.       DANIELE GIACOMINI.
000400 DATE-WRITTEN. 2005-03-08.
000500 ENVIRONMENT DIVISION.
000600 INPUT-OUTPUT SECTION.
000700*
000800 FILE-CONTROL.
000900     SELECT MIO-FILE ASSIGN TO "input.rel"
001000                     ORGANIZATION IS RELATIVE
001100                     ACCESS MODE IS RANDOM
001200                     RELATIVE KEY IS N-RECORD
001300                     FILE STATUS IS STATO-DEL-FILE.
001400*
001500 DATA DIVISION.
001600 FILE SECTION.
001700 FD  MIO-FILE
001800     LABEL RECORD IS STANDARD.
001900 01  MIO-RECORD  PIC X(20).
002000 WORKING-STORAGE SECTION.
002100 77  N-RECORD             PIC 9999 COMP VALUE IS ZERO.
002200 77  STATO-DEL-FILE       PIC XX.
002300 PROCEDURE DIVISION.
002400 MAIN.
002500     OPEN INPUT MIO-FILE.
002600     DISPLAY "FILE STATUS: ", STATO-DEL-FILE.
002700     PERFORM READ-FILE UNTIL STATO-DEL-FILE NOT = ZERO.
002800     CLOSE MIO-FILE.
002900     STOP RUN.
003000 READ-FILE.
003100     ADD 1 TO N-RECORD.
003200     READ MIO-FILE
003300          INVALID KEY DISPLAY "INVALID KEY!".
003400     DISPLAY "FILE STATUS: " STATO-DEL-FILE,
003500             " RECORD: ", N-RECORD, " ", MIO-RECORD.
003600

Il file indicato come MIO-FILE è associato in pratica al file input.rel. Si può supporre che questo file sia composto dall'elenco seguente di record logici:

  1. aaaaaaaaaaaaaaaaaaaa

  2. bbbbbbbbbbbbbbbbbbbb

  3. cccccccccccccccccccc

  4. dddddddddddddddddddd

Eseguendo il programma dell'esempio si potrebbe ottenere il testo seguente attraverso lo schermo:

FILE STATUS: 00
FILE STATUS: 00 RECORD: 0001 aaaaaaaaaaaaaaaaaaaa
FILE STATUS: 00 RECORD: 0002 bbbbbbbbbbbbbbbbbbbb
FILE STATUS: 00 RECORD: 0003 cccccccccccccccccccc
FILE STATUS: 00 RECORD: 0004 dddddddddddddddddddd
INVALID KEY!
FILE STATUS: 23 RECORD: 0005 dddddddddddddddddddd

Segue un altro esempio completo per la lettura di un file relativo, utilizzando un accesso dinamico, partendo dal primo record e selezionando i successivi attraverso la richiesta del prossimo:

Listato 674.20. Programma elementare che legge un file relativo, ad accesso dinamico.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID.   ESEMPIO-RELATIVO-DINAMICO.
000300 AUTHOR.       DANIELE GIACOMINI.
000400 DATE-WRITTEN. 2005-03-08.
000500 ENVIRONMENT DIVISION.
000600 INPUT-OUTPUT SECTION.
000700*
000800 FILE-CONTROL.
000900     SELECT MIO-FILE ASSIGN TO "input.rel"
001000                     ORGANIZATION IS RELATIVE
001100                     ACCESS MODE IS DYNAMIC
001200                     RELATIVE KEY IS N-RECORD
001300                     FILE STATUS IS STATO-DEL-FILE.
001400*
001500 DATA DIVISION.
001600 FILE SECTION.
001700 FD  MIO-FILE
001800     LABEL RECORD IS STANDARD.
001900 01  MIO-RECORD  PIC X(20).
002000 WORKING-STORAGE SECTION.
002100 77  N-RECORD             PIC 9999 COMP VALUE IS 1.
002200 77  STATO-DEL-FILE       PIC XX.
002300 PROCEDURE DIVISION.
002400 MAIN.
002500     OPEN INPUT MIO-FILE.
002600     DISPLAY "FILE STATUS: ", STATO-DEL-FILE.
002700     READ MIO-FILE
002800          INVALID KEY DISPLAY "INVALID KEY!".
002900     PERFORM READ-FILE UNTIL STATO-DEL-FILE NOT = ZERO.
003000     CLOSE MIO-FILE.
003100     STOP RUN.
003200 READ-FILE.
003300     DISPLAY "FILE STATUS: " STATO-DEL-FILE,
003400             " RECORD: ", N-RECORD, " ", MIO-RECORD.
003500     READ MIO-FILE NEXT RECORD
003600          AT END DISPLAY "END OF FILE!".
003700

Il file che viene letto è lo stesso dell'esempio precedente e il risultato si dovrebbe ottenere, si può vedere così:

FILE STATUS: 00
FILE STATUS: 00 RECORD: 0001 aaaaaaaaaaaaaaaaaaaa
FILE STATUS: 00 RECORD: 0002 bbbbbbbbbbbbbbbbbbbb
FILE STATUS: 00 RECORD: 0003 cccccccccccccccccccc
FILE STATUS: 00 RECORD: 0004 dddddddddddddddddddd
END OF FILE!

674.3.5   Istruzione «SELECT» per i file a indice

Lo schema sintattico semplificato per l'istruzione SELECT, da usare nel paragrafo FILE-CONTROL, per dichiarare un file organizzato a indici è quello che si può vedere nella figura successiva:

                            /                   \
                            |       DISK        |
SELECT file-name ASSIGN TO  <       ¯¯¯¯        >
¯¯¯¯¯¯           ¯¯¯¯¯¯     | literal-file-name |
                            \                   /

    .--               .--   --. --.
    |                 | AREA  |   |
    | RESERVE integer |       |   |
    | ¯¯¯¯¯¯¯         | AREAS |   |
    `--               `--   --' --'

    [ ORGANIZATION IS ] INDEXED
      ¯¯¯¯¯¯¯¯¯¯¯¯      ¯¯¯¯¯¯¯
    .--               /              \ --.
    |                 |  SEQUENTIAL  |   |
    |                 |              |   |
    | ACCESS MODE IS  <  RANDOM      >   |
    | ¯¯¯¯¯¯          |  ¯¯¯¯¯¯      |   |
    |                 |  DYNAMIC     |   |
    `--               \  ¯¯¯¯¯¯¯     / --'

    RECORD KEY IS data-name-1 [WITH DUPLICATES]
    ¯¯¯¯¯¯                          ¯¯¯¯¯¯¯¯¯¯
    [ ALTERNATE RECORD KEY IS data-name-2 [WITH DUPLICATES] ]...
      ¯¯¯¯¯¯¯¯¯                                 ¯¯¯¯¯¯¯¯¯¯
    [ FILE STATUS IS data-name-3 ].
           ¯¯¯¯¯¯

Un file organizzato a indice è un file che consente un accesso diretto ai record in base a una chiave costituita da una porzione del record stesso. A titolo di esempio, si può immaginare un file contenente i dati anagrafici dei dipendenti di un'azienda, che in una posizione precisa dei record riporta il numero di matricola di ognuno; in tal modo, il numero di matricola può essere usato per definire la chiave di accesso ai record.

Il file organizzato a indice può disporre di una o più chiavi di accesso e può essere consentita o meno la presenza di record con chiavi uguali.

Rispetto ai file organizzati sequenzialmente o in modo relativo, lo schema sintattico per i file organizzati a indice ha le dichiarazioni RECORD KEY e ALTERNATE RECORD KEY per poter specificare la chiave o le chiavi di accesso. Le metavariabili data-name-1 e data-name-2 devono essere nomi di porzioni di record, come dichiarato nella divisione DATA DIVISION, in corrispondenza della descrizione del record stesso. Naturalmente, l'opzione WITH DUPLICATES serve a dichiarare l'intenzione di gestire chiavi uguali su più record.

674.3.6   Riordino e fusione

Oltre ai file comuni, per i quali si stabilisce un'organizzazione e un tipo di accesso, sono previsti dei file da usare soltanto per ottenere un riordino o una fusione (sort, merge). Per questi file occorre una dichiarazione apposita con l'istruzione SELECT, secondo lo schema sintattico seguente:

                                       /                   \
                                       |       DISK        |
SELECT sort-merge-file-name ASSIGN TO  <       ¯¯¯¯        > .
¯¯¯¯¯¯                      ¯¯¯¯¯¯     | literal-file-name |
                                       \                   /

Viene proposto un esempio di riordino di file, nel quale, in particolare, si dichiarano i nomi dei file su disco, direttamente nell'istruzione SELECT:

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID.   ORDINA.
000300 AUTHOR.       DANIELE GIACOMINI.
000400 DATE-WRITTEN. 2005-02-25.
000500*
000600 ENVIRONMENT DIVISION.
000700*
000800 INPUT-OUTPUT SECTION.
000900*
001000 FILE-CONTROL.
001100*
001200     SELECT FILE-DA-ORDINARE     ASSIGN TO "input.seq".
001300     SELECT FILE-ORDINATO        ASSIGN TO "output.seq".
001400     SELECT FILE-PER-IL-RIORDINO ASSIGN TO "sort.tmp".
001500*
001600 DATA DIVISION.
001700*
001800 FILE SECTION.
001900*
002000 FD  FILE-DA-ORDINARE.
002100 01  RECORD-DA-ORDINARE           PIC X(80).
002200*
002300 FD  FILE-ORDINATO.
002400 01  RECORD-ORDINATO              PIC X(80).
002500*
002600 SD  FILE-PER-IL-RIORDINO.
002700*
002800 01  RECORD-PER-IL-RIORDINO.
002900     02  CHIAVE-ORDINAMENTO       PIC X(10).
003000     02  FILLER                   PIC X(70).
003100*
003200 PROCEDURE DIVISION.
003300*
003400 MAIN.
003500     SORT FILE-PER-IL-RIORDINO,
003600          ON ASCENDING KEY CHIAVE-ORDINAMENTO,
003700          USING FILE-DA-ORDINARE,
003800          GIVING FILE-ORDINATO.
003900*
004000     STOP RUN.
004100*

Come si può vedere, si vuole ordinare il file input.seq per generare il file output.seq, ordinato. Per fare questo, si usa un file intermedio, denominato sort.tmp. Al termine dell'operazione, non dovrebbe rimanere traccia del file intermedio.

Si osservi che non si rende necessaria l'apertura dei file coinvolti per portare a termine l'operazione.

L'esempio seguente riguarda la fusione: si hanno i file input-1.seq e input-2.seq ordinati e si vuole ottenere il file output.seq con la somma dei record, mantenendo l'ordinamento:

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID.   MERGE.
000300 AUTHOR.       DANIELE GIACOMINI.
000400 DATE-WRITTEN. 2005-02-25.
000500*
000600 ENVIRONMENT DIVISION.
000700*
000800 INPUT-OUTPUT SECTION.
000900*
001000 FILE-CONTROL.
001100*
001200     SELECT FILE-INPUT-1         ASSIGN TO "input-1.seq".
001300     SELECT FILE-INPUT-2         ASSIGN TO "input-2.seq".
001400     SELECT FILE-OUTPUT          ASSIGN TO "output.seq".
001500     SELECT FILE-PER-LA-FUSIONE  ASSIGN TO "merge.tmp".
001600*
001700 DATA DIVISION.
001800*
001900 FILE SECTION.
002000*
002100 FD  FILE-INPUT-1
002200 01  RECORD-1                     PIC X(80).
002300*
002400 FD  FILE-INPUT-2
002500 01  RECORD-2                     PIC X(80).
002600*
002700 FD  FILE-OUTPUT
002800 01  RECORD-OUTPUT                PIC X(80).
002900*
003000 SD  FILE-PER-LA-FUSIONE.
003100*
003200 01  RECORD-PER-LA-FUSIONE.
003300     02  CHIAVE-ORDINAMENTO       PIC X(10).
003400     02  FILLER                   PIC X(70).
003500*
003600 PROCEDURE DIVISION.
003700*
003800 MAIN.
003900     MERGE FILE-PER-LA-FUSIONE
004000           ON ASCENDING KEY CHIAVE-ORDINAMENTO,
004100           USING FILE-INPUT-1,
004200                 FILE-INPUT-2,
004300           GIVING FILE-OUTPUT.
004400*
004500     STOP RUN.
004600*

Si osservi che esistono compilatori COBOL, di buona qualità, che però non offrono le funzionalità di riordino e di fusione, oppure non in modo completo. È frequente l'assenza della funzione per la fusione dei file ordinati.

674.3.7   Paragrafo «I-O-CONTROL»

Il paragrafo I-O-CONTROL è opzionale e il suo scopo è quello di specificare l'utilizzo comune delle aree di memoria centrale adibite alla gestione dei file.

I-O-CONTROL.
¯¯¯¯¯¯¯¯¯¯¯
    .--      .--          --.                                       --.
    |        |  RECORD      |                                         |
    |        |  ¯¯¯¯¯¯      |                                         |
    |  SAME  |  SORT        |  AREA FOR file-name-1 [file-name-2]...  |... .
    |  ¯¯¯¯  |  ¯¯¯¯        |                                         |
    |        |  SORT-MERGE  |                                         |
    `--      `--¯¯¯¯¯¯¯¯¯¯--'                                       --'

L'utilità dell'utilizzo del paragrafo I-O-CONTROL dipende molto dal compilatore, che potrebbe anche limitarsi a ignorare l'istruzione SAME...AREA, in tutto o solo in parte. Tuttavia, quando l'istruzione SAME...AREA viene presa in considerazione, ci sono delle conseguenze nell'accesso ai file, che bisogna conoscere.

Per cominciare: si intuisce dallo schema sintattico che l'istruzione SAME...AREA inizia nell'area B del modulo di programmazione, si vede che il punto fermo è richiesto solo alla fine del gruppo di istruzioni SAME...AREA, inoltre sono evidenti quattro possibilità:

SAME AREA FOR file-name-1 [file-name-2]... .
¯¯¯¯
SAME RECORD AREA FOR file-name-1 [file-name-2]... .
¯¯¯¯ ¯¯¯¯¯¯
SAME SORT AREA FOR file-name-1 [file-name-2]... .
¯¯¯¯ ¯¯¯¯
SAME SORT-MERGE AREA FOR file-name-1 [file-name-2]... .
¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯

Utilizzando la prima forma dell'istruzione SAME AREA, si intende richiedere al compilatore che la gestione dei file elencati sia fatta condividendo tutto quello che si può condividere nella memoria centrale. Così facendo, nell'ambito del gruppo specificato, solo un file può essere aperto simultaneamente; inoltre, se si utilizzano più istruzioni SAME AREA, un file può appartenere soltanto a uno di questi raggruppamenti.

Utilizzando l'istruzione SAME RECORD AREA si richiede al compilatore di gestire lo spazio della memoria tampone (dei record) di un gruppo di file in modo comune. Così facendo, la lettura di un record di un file del gruppo, comporta il fatto che gli stessi dati siano disponibili come se fossero stati letti da tutti gli altri file del gruppo. I file di un gruppo definito con questa istruzione possono essere aperti simultaneamente, ma le operazioni di accesso ai dati non possono essere simultanee; inoltre, un file può appartenere a un solo raggruppamento di questo tipo.

Teoricamente, i file indicati in un raggruppamento con l'istruzione SAME AREA possono apparire anche in un raggruppamento con l'istruzione SAME RECORD AREA, ma in tal caso deve trattarsi di tutti quelli che appartengono al primo di questi due (tutti quelli in SAME AREA devono essere parte di quello in SAME RECORD AREA). Inoltre, questo fatto comporta che i file che si trovano anche in SAME AREA non possono essere aperti simultaneamente.

Nei manuali COBOL classici si sottolinea il fatto che la condivisione dei record offra dei vantaggi in velocità e in risparmio di memoria; in particolare si suggerisce in tali manuali la possibilità di dichiarare nel dettaglio uno solo dei record del gruppo, oppure la possibilità di ridefinire i record cambiando il punto di vista (il record rispetto a quello di un altro). Tuttavia, considerata la potenza elaborativa degli elaboratori attuali, dal momento che esiste comunque la possibilità di ridefinire la suddivisione di un record, l'uso di questo paragrafo diventa sconsigliabile, se non altro per le complicazioni che si creano nell'interpretazione umana del programma sorgente.

Le istruzioni SAME SORT AREA e SAME SORT-MERGE AREA sono equivalenti e consentono di condividere la memoria utilizzata per i file che servono specificatamente per il riordino o la fusione. Premesso che in questi raggruppamenti non possono apparire file che appartengono a un gruppo definito come SAME AREA, è invece possibile inserire anche nomi di file che non sono stati dichiarati per l'ordinamento o la fusione, ma la loro presenza fa sì che questi file non possano essere aperti quando invece lo sono quelli che si utilizzano proprio per tale scopo.

I file dichiarati con l'indicatore SD nella sezione FILE SECTION servono per portare a termine le operazioni di riordino e di fusione, ma si avvalgono di file in ingresso e di file in uscita, che vengono dichiarati normalmente con l'indicatore FD. Tutti i file coinvolti in un procedimento di riordino e di fusione, non devono essere aperti esplicitamente durante questa fase.

Tabella 674.28. Codici di due caratteri sullo stato dei file (FILE STATUS), secondo lo standard del 1985: il significato del primo dei due caratteri.

Codice Descrizione
0x
L'ultimo accesso al file si è concluso sostanzialmente con successo.
1x
Si è verificato un tentativo di leggere oltre la fine del file.
2x
Si è verificato un errore riferito alla chiave di accesso di un file organizzato a indici.
3x
Si è verificato un errore che impedisce di accedere ulteriormente al file.
4x
Si è verificato un errore «logico», dovuto a una sequenza errata nelle operazioni o al tentativo di eccedere rispetto ai limiti stabiliti.
9x
Si tratta di errori diversi, stabiliti senza uno standard precisato da chi ha realizzato il compilatore.

Tabella 674.29. Codici di due caratteri sullo stato dei file (FILE STATUS), secondo lo standard del 1985: significato dettagliato.

Codice Organizzazione sequenziale Organizzazione relativa Organizzazione a indici
00
Operazione eseguita con successo. idem idem
02
-- -- L'operazione ha avuto successo, ma è stata scoperta una chiave doppia: la lettura di un record evidenzia che è disponibile un altro record con la stessa chiave; la scrittura di un record risulta avere una chiave già presente in altri.
04
La lunghezza del record letto non corrisponde a quella che dovrebbe avere. idem idem
05
Il tentativo di aprire un file opzionale mancante è risultato nella sua creazione e apertura successiva. idem idem
07
Il file non si trova su nastro e le opzioni specifiche per tale tipo di unità, contenute nei comandi di apertura o di chiusura del file, sono state ignorate. -- --
10
Si è verificato un tentativo di leggere oltre la fine del file, oppure di leggere un file opzionale che non risulta presente. -- --
14
-- La dimensione in record del file è più grande della capacità della variabile usata come indice. Questo tipo di errore si può manifestare quando si tenta una lettura sequenziale che dovrebbe incrementare automaticamente il valore dell'indice, ma si trova a non poterlo fare. --
21
-- -- Si è verificato un errore di sequenza nelle chiavi durante un accesso sequenziale al file.
22
-- Si è verificato un tentativo di scrivere un record già esistente (senza prima averlo cancellato). Si è verificato un tentativo di scrivere un record con chiave doppia, quando ciò non è consentito.
23
-- Il record richiesto non esiste. idem
24
-- Tentativo di scrittura oltre il limite della dimensione consentita, oppure tentativo di scrittura sequenziale di un record che ha un numero più grande della capacità della variabile usata come chiave. Tentativo di scrittura oltre il limite della dimensione consentita.
30
Errore permanente senza altre indicazioni. idem idem
34
Si è verificato un errore dovuto a un tentativo di scrittura oltre il limite fisico del file. -- --
35
Non è stato possibile aprire un file indispensabile. idem idem
36
L'operazione richiesta non è gestita dall'unità che contiene il file. idem idem
38
È stata tentata l'apertura di un file che risulta essere stato chiuso con l'opzione LOCK. idem idem
39
È stata tentata l'apertura di un file, le cui caratteristiche reali sono incompatibili con quelle dichiarate nel programma. idem idem
41
È stato aperto un file che risulta essere già aperto. idem idem
42
È stato chiuso un file che non risultava essere aperto. idem idem
43
Non è stato eseguito un comando READ prima del comando REWRITE. Durante un accesso sequenziale, non è stato eseguito un comando READ prima del comando REWRITE o del comando DELETE. Durante un accesso sequenziale, non è stato eseguito un comando READ prima del comando REWRITE o del comando DELETE.
44
Si è verificato un problema legato alla dimensione del record. idem idem
46
Durante un accesso sequenziale in lettura, si è verificato un errore, successivo a un altro tentativo fallito di lettura. idem idem
47
Tentativo di lettura di un file che non risulta essere aperto per questo tipo di accesso. idem idem
48
Tentativo di scrittura di un file che non risulta essere aperto per questo tipo di accesso. idem idem
49
Tentativo di riscrittura di un file che non risulta essere aperto per questo tipo di accesso. idem idem

Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome divisione_171_environment_division_187.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory