14.4. Vstup logických vět do třídění, příkaz RELEASE Pro určení zdroje logických vět vstupujících do třídění má uživatel dvě možnosti: zadat vstupní rutinu, v níž bude sám logické věty připravovat a předávat je příkazem RELEASE systémovému třídicímu programu (zadává se pomocí klauzule INPUT PROCEDURE v příkazu SORT), anebo uvést jméno jednoho nebo několika souborů obsahujících logické věty, které mají být setříděny (zadává se pomocí klauzule USING v příkazu SORT nebo MERGE). A) Vstupní rutina, klauzule INPUT PROCEDURE Vstupní rutinu může uživatel zadat pouze v příkazu SORT, a to pomocí klauzule INPUT PROCEDURE IS procedura-1 [{THRU|THROUGH} procedura-2] V tomto případě příkaz SORT v podstatě provede příkaz PERFORM procedura-1 [{THRU|THROUGH} procedura-2] Odskočí se tedy na začátek procedury-1 (tj. na začátek vstupní rutiny) a provádějí se příkazy zde uvedené. Správný průběh třídění je možný jen tehdy, má-li vstupní rutina následující strukturu: 1) Na jejím začátku jsou vhodné inicializační příkazy, např. otevření vstupního souboru, nastavení pomocných položek apod. (Na začátek vstupní rutiny se totiž odskakuje pouze jednou na začátku činnosti příkazu SORT - nikoliv při každé logické větě!) 2) Dále následují příkazy, pomocí nichž uživatel umístí do 01 popsané za SD (tzn. do paměti) tu logickou větu, kterou chce předat do třídění (většinou ji přečte z nějakého vstupního souboru a po případné kontrole a úpravě ji přesune z 01 za FD do 01 za SD). 3) Pak uživatel provede příkaz RELEASE (viz dále). Příkaz RELEASE předá řízení systémovému třídicímu programu, jenž převezme připravenou logickou větu a přesune ji z 01 za SD do svých pracovních polí s přihlédnutím k jejím třídicím klíčům. Až systémový třídicí program požaduje od vstupní rutiny další logickou větu, předá řízení zpět do vstupní rutiny. Dokončí se provádění příkazu RELEASE a přechází se na provádění následujícího příkazu. 4) Nejsou-li dosud odeslány všechny logické věty, které uživatel hodlá ve vstupní rutině odeslat do třídění, musí uživatel přejít znovu na provádění bodu 2. 5) Po odeslání všech logických vět musí uživatel přejít na provádění závěrečných příkazů vstupní rutiny (např. uzavření vstupního souboru apod.). Po provedení posledního příkazu vstupní rutiny se přijde na návratový můstek vygenerovaný překladačem na konci vstupní rutiny, jenž automaticky předá řízení zpět do příkazu SORT (přesně stejně, jako kdyby na konci vstupní rutiny končil úsek programu prováděný jednoduchým příkazem PERFORM). Vstupní rutina má tedy tvar posloupnosti procedur, která se jako celek provádí při jednom třídění (tj. při jednom provádění příkazu SORT) pouze jednou. Uvnitř vstupní rutiny však bude pravděpodobně cyklus, při jehož každém opakování se příkazem RELEASE odešle do třídění jedna logická věta. Příkaz RELEASE Příkaz RELEASE smí být použit výhradně ve vstupní rutině při třídění prováděném příkazem SORT. Před jeho provedením musí uživatel uložit do 01 v paměti logickou větu, která má být odeslána do třídění. Příkaz RELEASE pak tuto logickou větu (tzn. okamžitý obsah 01) předá systémovému třídicímu programu, který ji převezme a zpracuje. Po ukončení provádění příkazu RELEASE může uživatel připravovat další logickou větu. (Příkaz RELEASE má tedy při odesílání logických vět do třídění stejnou úlohu jako příkaz WRITE při vytváření sekvenčního souboru.) Po provedení příkazu RELEASE nezůstává právě odeslaná logická věta nadále obsažena v 01 popsané za SD, takže uživatel nemůže její části využít při vytváření další logické věty. Formát: RELEASE logická-věta [FROM {literál | položka | fig.konst. | ALL-klauzule}] [LENGTH {celé-číslo | celočíselná-položka}] Pravidla: 1) Za slovem RELEASE musí být uvedeno jméno některé 01 (případně kvalifikované jménem třídicího souboru) popsané za klauzulí SD toho třídicího souboru, jemuž odpovídající třídění se právě provádí. (Provedení příkazu RELEASE pro třídicí soubor, jemuž odpovídající třídění není právě v činnosti, způsobí vážnou chybu.) 2) Klauzule "FROM argument" přípustná v příkazu RELEASE má přesně stejný význam jako u příkazu WRITE (viz 8.3.). Způsobí tedy, že před vlastním odesláním obsahu 01 systémovému třídicímu programu se ještě provede příkaz MOVE argument TO logická-věta kde příjmovou položkou je právě ta 01, která je uvedena za slovem RELEASE. Pro odeslání logické věty do třídění má tedy uživatel dvě možnosti: a) Naplnit logickou větu do 01 sám a provést pak příkaz RELEASE bez klauzule FROM. b) Připravit logickou větu ve vhodné položce (anebo ji vyjádřit literálem, figurativní konstantou nebo ALL-klauzulí) a provést pak příkaz RELEASE s klauzulí FROM. 3) Pro určení délky logické věty odesílané do třídění platí stejná pravidla jako u příkazu WRITE (viz 8.3.): a) Při RECORDING F se vždy pracuje s pevnou délkou logických vět; odesílaná logická věta má vždy délku rovnou hodnotě parametru RECSIZE (viz 4.4.3.) a proto volba 01 uvedené za slovem RELEASE nemá žádný význam. Klauzule LENGTH nesmí být v příkazu RELEASE uvedena. b) Při RECORDING V odesílá příkaz RELEASE bez klauzule LENGTH logickou větu o právě té délce, jakou má 01 uvedená v příkazu RELEASE (u 01 s proměnnou délkou se vypočítá okamžitá hodnota její délky). c) Při RECORDING V smí být v příkazu RELEASE uvedena klauzule LENGTH. Pak bude odeslána logická věta o délce rovné hodnotě argumentu uvedeného za slovem LENGTH (podrobný popis viz u příkazu WRITE, 8.3.). Příklad: Máme setřídit a zapsat na disk logické věty získané čtením vstupního souboru STITEK. Každá logická věta tohoto souboru obsahuje 4 logické věty po 20 bytech, které se mají třídit podle prvních 5 bytů logické věty dle alfanumerického srovnání, a to vzestupně. IDENTIFICATION DIVISION. PROGRAM-ID. A31W8UT7. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT STITEK ASSIGN S-STITEK. SELECT DISK ASSIGN S-DISK. SELECT TRID ASSIGN S-TRID. DATA DIVISION. FILE SECTION. FD STITEK. 01 FILLER. 02 KUS PIC X(20) OCCURS 4. FD DISK. 01 FILLER PIC X(20). SD TRID. 01 BUFER. 02 KLIC PIC X(5). 02 FILLER PIC X(15). WORKING-STORAGE SECTION. 77 PORADI PIC S9 COMP-3. PROCEDURE DIVISION. SORT TRID ASCENDING KLIC INPUT PROCEDURE VSTUP THRU KONEC GIVING DISK. STOP RUN. VSTUP. OPEN INPUT STITEK. CTENI. READ STITEK AT END GO TO KONEC. MOVE 1 TO PORADI. NECTENI. RELEASE BUFER FROM KUS(PORADI). IF PORADI < 4 ADD 1 TO PORADI GO TO NECTENI ELSE GO TO CTENI. KONEC. CLOSE STITEK. B) Klauzule USING Klauzule USING, která může být uvedena jak v příkazu SORT, tak i v příkazu MERGE, má formát USING jméno-souboru ... Za slovem USING je třeba uvést jméno jednoho nebo několika souborů (u příkazu SORT bývá většinou pouze jeden, u příkazu MERGE bývají alespoň dva) obsahujících logické věty, které mají být setříděny. Systémový třídicí program každý ze souborů uvedených v klauzuli USING otevře, přečte z něj sekvenčně všechny jeho logické věty a převezme je do třídění, načež po zjištění konce souboru tento soubor uzavře. Uživatel nezadává žádnou vstupní rutinu a nepoužívá příkaz RELEASE. Každý soubor uvedený v klauzuli USING je v přeloženém programu representován instrukcemi, které jsou prakticky stejné, jako kdyby vznikly překladem vstupní rutiny tvaru: A. OPEN INPUT soubor. B. READ soubor AT END GO TO C. RELEASE třid-věta FROM soub-věta. GO TO B. C. CLOSE soubor. Zde "třid-věta" označuje tu 01, která je popsána za SD jako první, a "soub-věta" označuje tu 01, která je popsána za FD příslušného souboru jako první ze všech 01 neuvedených v klauzuli LABEL. Vstupní rutina je sice přípustná pouze v příkazu SORT, obdobné zpracování se však provádí i se souborem uvedeným v klauzuli USING v příkazu MERGE. Z uvedeného plynou následující pravidla a požadavky: a) Soubory uvedené v klauzuli USING musí být buďto sekvenční soubory (z nichž lze číst) nebo indexové resp. relativní soubory čtené sekvenčně. b) Na začátku provádění příkazu SORT resp. MERGE nesmí být tyto soubory již otevřené, neboť příkaz SORT resp. MERGE si je otevírá sám. c) Soubor se vždy otevírá bez klauzule WITH NO REWIND i bez klauzule REVERSED. d) Není-li v SD uvedeno RECORDING V, způsobí klauzule FROM v implicitním příkazu RELEASE normální přesun "MOVE soub-věta TO třid-věta" dle pravidel příkazu MOVE. Logická věta odesílaná do třídění má pak délku rovnou délce 01 za SD (přesněji: parametru RECSIZE) nezávisle na tvaru a délce "soub-věty" získané příkazem READ. (V případě příkazu MERGE je zde teoretická výjimka: přesun se provádí vždy alfanumericky s ignorováním případné klauzule JUST, přičemž má-li soubor uvedený v klauzuli USING RECORDING V nebo U, bere se jako délka vysílající položky skutečná délka právě přečtené logické věty tohoto souboru.) e) Je-li v SD uvedeno RECORDING V, má klauzule FROM v implicitním příkazu RELEASE jiný význam než u explicitně použitého příkazu RELEASE a než při RECORDING F: Implicitní příkaz RELEASE předá do třídění logickou větu o přesně stejné délce a obsahu, jako má logická věta souboru uvedeného za USING, právě přečtená příkazem READ. Tak tomu bude nezávisle na tom, zda soubor uvedený za USING má RECORDING F nebo V nebo U (implicitní příkaz RELEASE totiž automaticky převede získanou logickou větu do formátu V). f) Příkaz SORT resp. MERGE na závěr své činnosti uvedený soubor sám uzavře, a to příkazem CLOSE bez klauzulí REEL, UNIT, WITH NO REWIND i WITH LOCK.