602SQL-Úplná dokumentace Index  

Deklarace handleru (SQL)

deklarace_handleru ::= DECLARE { CONTINUE | EXIT | REDO | UNDO } HANDLER FOR výjimka 
    {, výjimka }… příkaz;
výjimka ::=  identifikátor_výjimky | SQLSTATE [ VALUE ] sqlstate | SQLEXCEPTION | SQLWARNING 
    | NOT FOUND 

Touto deklarací se handler zadaný příkazem přiřadí ke specifikovaným výjimkám nebo třídám výjimek a může se v rozsahu platnosti této deklarace (v tomto složeném příkazu) uplatnit při ošetření výjimky.

Je-li v deklaraci handleru uveden identifikátor_výjimky, musí být dříve deklarován v deklaraci výjimky. Handler se zavolá, pokud je tato výjimka aktivována příkazem SIGNAL. Stejná výjimka nesmí být uvedena dvakrát ve stejných nebo různých deklaracích handleru ve stejném rozsahu platnosti. Je-li v deklaraci této výjimky uveden sqlstate, pak handler je přiřazen i k tomuto sqlstate.

Je-li v deklaraci handleru uvedeno SQLSTATE sqlstate, pak handler se zavolá, kdykoli tento sqlstate nastane.

Je-li v deklaraci handleru uvedeno slovo SQLEXCEPTION, SQLWARNING nebo NOT FOUND, handler se zavolá, nastane-li libovolná chyba kromě čtení neexistujícího záznamu v příkazu FETCH (pro SQLEXCEPTION), libovolné varování (pro SQLWARNING) nebo čtení neexistujícího záznamu v příkazu FETCH (pro NOT FOUND). Výjimka Čtení z neexistujícího záznamu (sqlstate '02000') je výjimečná tím, že handler pro ní se musí deklarovat při každém použití konstrukce LOOP...FETCH...END LOOP, zřejmě z tohoto důvodu má tak výsadní postavení.

Nastane-li při provádění SQL příkazů výjimka, hledá se nejbližší handler pro tuto výjimku (nejprve v tomto složeném příkazu, poté ve vnějších složených příkazech). Je-li nějaký handler nalezen, pak v závislosti na druhu handleru:

Handlery REDO a UNDO smějí být deklarovány pouze v atomickém složeném příkazu. Nelze v nich používat transakční příkazy.

Globální handlery SQL serveru se deklarují v proceduře Module_globals.

Příklad použití:

při průchodu kurzoru je třeba testovat existenci dalšího řádku

DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN SET err_notfound=TRUE; END;
LabelLoop: LOOP 
    FETCH NEXT FROM cur INTO TatoFirma, TatoHodnota; 
    IF err_notfound IS TRUE THEN LEAVE LabelLoop; END IF;
...

Pokud se nanajde zbozi v tabulce, přiřaď mu číslo -1:

...
    BEGIN
      DECLARE CONTINUE HANDLER FOR SQLSTATE '21000' BEGIN SET cis_zb = -1; END;
      SELECT id_zbozi INTO cis_zb
      FROM TZbozi WHERE ...; 
    END;
...

V konverzní funkci může dojít k chybě 22018 (tj. nelze zkonvertovat), v takovém případě se chyba odchytí a funkce vrátí NULL.

FUNCTION `Konvertuj( IN inputChar NCLOB) ) RETURNS CLOB COLLATE CZ_ISO;
BEGIN
  DECLARE CONTINUE HANDLER FOR SQLSTATE '22018' BEGIN RETURN NULL; END;
  RETURN CAST(inputChar) AS CLOB COLLATE CZ_ISO);
END