|
![]() | Sekvence | ![]() | Jazyk SQL a jeho implementace | Transakce a body návratu | ![]() |
Kurzory v SQL jsou nástrojem, jak programově zpracovat odpověď na dotaz. Umožňují číst řádky této odpovědi, modifikovat je nebo rušit je. Kurzor je vždy nastaven na některé řádce odpovědi, je před některou řádkou nebo za poslední řádkou odpovědi.
Lokální kurzory lze deklarovat v každém složeném příkazu. Mimo to lze pracovat s globálními kurzory, kterými jsou dotazy uložené v databázové aplikaci (vytvořené příkazem CREATE VIEW nebo klientským návrhářem dotazů).
Každý kurzor musí být nejprve otevřen příkazem OPEN. Poté lze procházet a číst jeho řádky příkazem FETCH, odvolávat se na jeho běžný záznam v příkazech UPDATE CURRENT OF a DELETE CURRENT OF a nakonec jej uzavřít příkazem CLOSE.
Neuzavřené lokální kurzory jsou automaticky uzavřeny při opuštění složeného příkazu, v němž jsou deklarovány.
Jiný způsob, jak otevřít kurzor, projít a zpracovat postupně všechny jeho záznamy a kurzor uzavřít, nabízí řídicí příkaz FOR. Při použití FOR není třeba deklarovat NOT FOUND handler.
Vyskytne-li se v době otevírání kurzoru chyba (tj. ne chyba syntaktická=kompilační, ale např. některá hodnota nejde zkonvertovat, k některé hodnotě nemáte právo apod.), záleží reakce na typu kurzoru. Je-li needitovatelný nebo INSENSITIVE, vytváří se vždy nová kopie kurzoru a musí se tedy kompletně vyhodnotit, proto se chyba projeví už zde. Naopak je-li kurzor editovatelný a SENSITIVE, tato chyba se projeví až při průchodu kurzorem ve FOR cyklu nebo pomocí FETCH na daném záznamu. Je-li chyba zachycena CONTINUE handlerem, pokračuje se dalším záznamem. Není-li nebo nejde-li handlovat, provede se rollback.
Příklad použití:
PROCEDURE Nejlepsi (OUT MaxFirma CHAR(20), OUT MaxObjed INT);
BEGIN
DECLARE err_notfound BIT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' BEGIN SET err_notfound=TRUE; END;
DECLARE cur CURSOR FOR
SELECT Firmy.adresa, CAST (SUM(Objednavky.objed) AS INT)
FROM Firmy, Objednavky
WHERE Objednavky.firma=Firmy.firma
GROUP BY Firmy.firma
FOR READ ONLY;
DECLARE TatoHodnota INT;
DECLARE TatoFirma CHAR(20);
SET MaxObjed = 0;
OPEN cur;
LabelLoop: LOOP
FETCH NEXT FROM cur INTO TatoFirma, TatoHodnota;
IF err_notfound IS TRUE THEN LEAVE LabelLoop; END IF;
IF TatoHodnota > MaxObjed THEN
SET MaxObjed = TatoHodnota;
SET MaxFirma = TatoFirma;
END IF;
END LOOP LabelLoop;
CLOSE cur;
END ;
Seznam subsekcí:
![]() | Sekvence | ![]() | Jazyk SQL a jeho implementace | Transakce a body návratu | ![]() |