8.4. Příkaz START Formát: START jméno-souboru [ SECONDARY KEY celé-číslo ] - - - - - - | |EQUAL TO| |alfanumerický-literál| | | KEY IS < > < > | | | = | | položka | | - - - - - - [ INVALID KEY příkaz ... ] Pravidlo: Příkaz START je přípustný pouze u indexového souboru se sekvenčním přístupem otevřeného OPEN INPUT nebo OPEN I-O (tzn. při sekvenčním čtení) a dále u indexového souboru s ACCESS DYNAMIC. Funkce: Příkaz START nečte žádnou logickou větu. Pouze způsobí nastavení pozice v indexovém souboru tak, že příští příkaz READ přečte tu logickou větu souboru dat, která má logický klíč určený příkazem START (viz dále). Následující příkazy READ (při ACCESS DYNAMIC pouze příkazy READ s NEXT nebo s AT END) pak budou číst sekvenčně následující logické věty souboru dat v pořadí dle rostoucího resp. neklesajícího logického klíče, a to až do nového příkazu START případně až do konce souboru anebo do příkazu CLOSE. Při ACCESS DYNAMIC je sekvenční čtení ukončeno též při provedení příkazu READ bez NEXT i bez AT END nebo příkazu WRITE. Pravidla: 1) Klauzule "SECONDARY KEY" se používá tehdy, pracuje-li se u tohoto indexového souboru též s jedním nebo s několika sekundárními logickými klíči. Při čtení logických vět (ať už sekvenčním nebo přímém) se vždy pracuje podle právě jednoho z definovaných logických klíčů, tzn. podle primárního logického klíče anebo podle některého ze sekundárních klíčů. (Naproti tomu opravování, vyřazování a vkládání logických vět jsou akce nezávislé na tom, podle kterého logického klíče se pracuje.) Při otevření souboru se aktuálním logickým klíčem stane primární klíč. Při výpočtu se pak bude používat určitý logický klíč tak dlouho, dokud nebude určen jakožto aktuální jiný logický klíč, což se provede zadáním klauzule "SECONDARY KEY celé-číslo", která smí být uvedena v příkazu START a v příkazu READ provádějícím přímé čtení: a) Je-li v příkazu START uvedena klauzule "SECONDARY KEY celé-číslo", bude nadále aktuálním logický klíč s pořadovým číslem uvedeným v této klauzuli. (Chceme-li tedy, aby se aktuálním klíčem stal primární klíč, musíme v příkazu START uvést klauzuli "SECONDARY KEY 0".) Této volbě aktuálního logického klíče musí též odpovídat hodnota logického klíče uložená před provedením příkazu START do NOMINAL-položky nebo vyjádřená argumentem, uvedeným v klauzuli KEY. b) Není-li v příkazu START uvedena klauzule "SECONDARY KEY celé-číslo" nebo je-li uvedena a číslo sekundárního indexu neexistuje, zůstává i nadále aktuálním logickým klíčem ten logický klíč, který byl aktuálním před provedením příkazu START. I v tomto případě musí zadaná hodnota logického klíče odpovídat okamžité volbě aktuálního logického klíče. 2) Není-li v příkazu START uvedena klauzule KEY, musí uživatel před provedením příkazu START vložit do NOMINAL-položky logický klíč té logické věty, která má být přečtena následujícím příkazem READ. Pokud v souboru dat neexistuje logická věta s klíčem přesně rovným zadanému obsahu NOMINAL-položky, vznikne výjimečný stav, jenž při uvedení klauzule INVALID KEY způsobí její uplatnění. 3) Je-li v příkazu START uvedena klauzule KEY, platí tato pravidla: a) Slovo IS je bezvýznamné, možnosti =, EQUAL a EQUAL TO jsou rovnocenné. b) Argument uvedený v klauzuli KEY musí mít délku nejvýše rovnou délce NOMINAL-položky. Jedná-li se o položku, musí do ní uživatel před provedením příkazu START dát vhodný obsah (viz dále). Na začátku provádění příkazu START bude tento argument uložen (zleva) do NOMINAL-položky a je-li kratší než NOMINAL-položka, bude doplněn do délky NOMINAL-položky binárními nulami. Argumentem uvedeným v klauzuli KEY smí být i položka s proměnnou délkou. c) První příkaz READ následující po příkazu START přečte tu logickou větu souboru dat, jejíž logický klíč je roven argumentu uvedenému v klauzuli KEY doplněnému zprava binárními nulami, anebo (není-li v souboru dat taková logická věta) logickou větu s logickým klíčem nejblíže vyšším. d) Je-li argument uvedený v klauzuli KEY větší než nejvyšší logický klíč v aktuálním indexu, vznikne výjimečný stav, jenž při uvedení klauzule INVALID KEY způsobí její uplatnění. 4) Pokud aktuální logický klíč připouští duplikované hodnoty logických klíčů (tj. aby několik logických vět mělo týž logický klíč), nastaví příkaz START pozici v souboru na první logickou větu s logickým klíčem předepsané vlastnosti. 5) Výjimečné stavy popsané v bodech 2) a 3d) způsobují přednostně uplatnění klauzule INVALID KEY; Teprve při neuvedení klauzule INVALID KEY způsobují vyvolání deklarativní sekce pro ošetření chyb vstupu/výstupu (viz 5.5.2.). 6) Dojde-li při provádění příkazu START k výjimečnému stavu, pak příkaz START nenastaví pozici v souboru dat. Nesmí pak následovat příkaz READ pro sekvenční čtení (způsobil by chybu a ukončení výpočtu), smí následovat pouze nový příkaz START nebo příkaz CLOSE (při ACCESS DYNAMIC též příkaz READ nebo příkaz WRITE). 7) Příkaz START nesmí být proveden mezi příkazem READ a příkazem REWRITE resp. DELETE opravujícím resp. vyřazujícím logickou větu přečtenou příkazem READ. 8) Při konci souboru (tj. při uplatnění klauzule AT END v příkazu READ pro sekvenční čtení resp. při odpovídajícím vyvolání deklarativní sekce) je přípustné bez uzavření souboru a nového otevření provést příkaz START a normálně pokračovat ve zpracování. 9) Pokud při sekvenčním čtení indexového souboru není mezi příkazem OPEN a prvním příkazem READ proveden příkaz START, bude tento první příkaz READ číst první logickou větu souboru dat (s nejmenším logickým klíčem v primárním indexu); žádný implicitní příkaz START se neprovádí a obsah NOMINAL-položky se nijak nevyužívá. 10) Během zpracování indexového souboru lze použít příkaz START i několikrát. Každý příkaz START znamená přechod na nový úsek souboru dat, přičemž tento přechod může znamenat přeskok v souboru dat jak vpřed, tak i vzad. Po každém příkazu START následují příkazy READ (obvykle větší počet, smí však být i jediný nebo i žádný) a případně též příkazy REWRITE a DELETE, jimiž se logické věty tohoto souvislého úseku čtou a případně opravují resp. vyřazují. Příkaz START takto umožňuje kombinaci přímého a sekvenčního zpracování: zpracovává se postupně několik souvislých úseků souboru dat, jejichž začátky se ovšem vyhledávají přímo. 11) Není-li v klauzuli SELECT uvedena podklauzule NOMINAL KEY, rozumí se NOMINAL-položkou položka uvedená v klauzuli RECORD KEY, a není-li ani tato uvedena, pak ta část logické věty 01, která odpovídá aktuálnímu logickému klíči. Příklad: Budeme zpracovávat indexový soubor dat, jehož logické věty mají délku 50 bytů, přičemž (primární) logický klíč je na 11. - 16. bytu každé logické věty. První dva znaky logického klíče vyjadřují číslo závodu, další čtyři jeho znaky vyjadřují číslo zaměstnance. Máme vytvořit program, který čte z pomocného souboru čísla závodu, načež program pro každé takové číslo vytiskne všechny zaměstnance příslušného závodu. IDENTIFICATION DIVISION. PROGRAM-ID. MEZEK. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT ZAJIC ASSIGN I-KRALIK RECORD KOZA NOMINAL KOZEL. SELECT KRUTA ASSIGN S-HUSA. DATA DIVISION. FILE SECTION. FD ZAJIC . 01 HOLUB. 02 FILLER PIC X(10). 02 KOZA. 03 ZAVOD PIC XX. 03 ZAMESTNANEC PIC X(4). 02 FILLER PIC X(34). FD KRUTA. 01 KRAVA PIC XX. WORKING-STORAGE SECTION. 77 KOZEL PIC X(6). PROCEDURE DIVISION. OPEN INPUT ZAJIC KRUTA. Q1. READ KRAVA AT END CLOSE ZAJIC KRUTA STOP RUN. DISPLAY NEWPAGE. START ZAJIC KEY = KRAVA INVALID KEY DISPLAY 'PRILIS VELKE CISLO ZAVODU ' KRAVA GO TO Q1. DISPLAY 'ZAVOD CISLO ' KRAVA. DISPLAY SPACE. Q2. READ ZAJIC AT END GO TO Q1. IF ZAVOD NOT = KRAVA GO TO Q1. DISPLAY HOLUB. GO TO Q2. Podklauzule "RECORD KOZA" v klauzuli SELECT je pouze poznámková, neboť poloha i délka logického klíče se získávají z indexového souboru. V klauzuli SELECT je možno vynechat podklauzuli "NOMINAL KEY" a vynechat též popis položky KOZEL. Příkaz START by pak uložil argument KRAVA (doplněný binárními nulami) přímo do primárního logického klíče, který je částí 01.