602SQL-Úplná dokumentace Index  

Příkaz FOR (SQL)

příkaz_FOR ::= [ návěští : ] FOR řídicí_proměnná AS [ jméno_kurzoru [ SENSITIVE | INSENSITIVE] 
    CURSOR FOR ] specifikace_kurzoru 
DO příkaz… END FOR [ návěští ];

Příkaz FOR slouží k zopakování posloupnosti příkazů pro všechny řádky odpovědi na dotaz zadaného specifikací kurzoru. Provádění příkazu skončí předčasně tehdy, provede-li se příkaz LEAVE na vnější návěští nebo dojde k chybě.

V příkazech obsažených uvnitř příkazu FOR lze s hodnotami sloupců na aktuálním řádku kurzoru pracovat pomocí zápisu ve tvaru:

řídicí_proměnná.jméno_sloupce

Lze použít např. pro předání hodnoty sloupce proceduře - viz příklad 2. Pokud však opačně přiřadíte sloupci novou hodnotu, na datech v databázi se to neprojeví.

Pro editaci sloupce je nutno použít příkazu UPDATE CURRENT OF, pak se na sloupce odkazuje pouze jejich jménem, bez řídicí proměnné (viz příklad 1). Kurzor v tomto případě nesmí být INSENSITIVE - pokud ano, změny se neuloží.

Je-li uvedeno koncové návěští, pak musí být uvedeno také stejné počáteční návěští. Uvnitř příkazu FOR nesmí být žádný příkaz označen stejným návěštím.

Význam specifikace kurzoru a specifikací SENSITIVE a INSENSITIVE je popsán v části o deklaraci kurzoru.

Je-li uvedeno jméno kurzoru, lze toto jméno uvnitř příkazu FOR používat v příkazech UPDATE CURRENT OF a DELETE CURRENT OF, ale nikoli v příkazech OPEN, CLOSE nebo FETCH.


Příklad použití č.1:

Změňte cenu u položek ceníku takto: položky ceníku začínající na X +10%, začínající na A +100%, ostatní smazat.

PROCEDURE ZmenaCeniku();
BEGIN 
  FOR radek AS curcen SENSITIVE CURSOR FOR 
    SELECT cislo_pol, cena
    FROM Cenik
  DO 
    BEGIN
     IF SUBSTRING(radek.cislo_pol FROM 1 FOR 1) = 'X' THEN 
       UPDATE  SET cena = cena*1.1 WHERE CURRENT OF curcen;
     ELSEIF SUBSTRING(radek.cislo_pol FROM 1 FOR 1) = 'A' THEN 
       UPDATE  SET cena = cena*2 WHERE CURRENT OF curcen;
     ELSE
       DELETE WHERE CURRENT OF curcen;
     END IF;
    END;
  END FOR;
END;

Příklad použití č.2:

Příklad z aplikace Knihovna - zrušit rezervace knih, které jsou rezervovány déle než limit.

PROCEDURE CancelRes(IN lim INT);
BEGIN

  DECLARE PROCEDURE CheckResBook(code CHAR(8));  // pomocná lokální procedura
  BEGIN
    DECLARE pocet INT;
    SELECT COUNT(co) INTO pocet                // kolikrát je daná kniha rezervována?
    FROM Rezervace
    WHERE Rezervace.co = code;

    IF pocet = 1 THEN                          // pouze jednou, pak odstraň označení
      UPDATE Knihy
      SET Knihy.rezervovana = FALSE
      WHERE Knihy.kod = code;
    END IF;
  END;

  FOR radek AS pomc SENSITIVE CURSOR FOR      // pro všechny rezervace po limitu proveď
    SELECT * 
    FROM Rezervace
    WHERE CURRENT_DATE - Rezervace.dat_rez > lim
  DO BEGIN
      CALL CheckResBook(radek.co);            // změň příznak, je-li rezervace jediná
      DELETE WHERE CURRENT OF pomc;           // smaž záznam v tab. Rezervace
    END;
  END FOR;
END

Příklad použití č.3:

Průchod tabulkou:

FOR radek_tabulky AS TABLE Tabulka_pokusna DO
  ...
  CALL Log_write(radek_tabulky.sloupec1);
END FOR;