4. Handlers
Amb SQL podem gestionar els errors generats per les ordres SQL. Si per exemple fem un SELECT a una taula que no existeix, ens dóna l'error 1146. Podem fer que si alguna vegada ocorre eixe error, que faça tal cosa. Per a aconseguir això cal definir un HANDLER.
Veiem primer un exemple i després explicarem la sintaxi.
Exemple: PE de prova per a saber si hi ha hagut error de clau duplicada
Estem dient que si més endavant ocorre l'error 23000 (error per clau duplicada), que la variable @err tinga el valor 1 i que "CONTINUE" executant-se el tros de codi del bloc BEGIN-END.
Si executem això vorem que no ha aparegut cap error i, a més, el valor de @x és 3. Per què?
(*) L'error provocat no apareix ja que ha estat "agafat" pel handler que hem creat. A més, com que eixe handler estava definit com a CONTINUE, la rutina ha continuat executant-se.
Si en compte de CONTINUE, el handler haguera estat definit com EXIT, en executar el 2n INSERT hauria acabat el procediment. En eixe cas @x valdria 2.
4.1. Sintaxi del HANDLER
On tenim:
- sentència: pot ser una ordre SQL simple o composta (bloc
BEGIN ... END). - tipus_handler: indica si continuen executant-se les següents instruccions a l'error o no:
CONTINUE: continuar la rutina.EXIT: se n'ix del blocBEGIN ... ENDon està.
- codi_error: identificador de l'error (o llista d'errors) que es vol controlar.
Es pot posar de distintes formes:
codi_error_mysqlSQLSTATE codi_error_sqlstatenom_errorSQLWARNINGNOT FOUNDSQLEXCEPTION
4.2. Codis d'error
4.2.1. codi_error_mysql
És un codi d'error numèric.
Exemple: 1022 -- Clau duplicada
Problema
Estos codis només són vàlids per a MySQL. Per tant, no és portable a altres SGBD.
4.2.2. SQLSTATE codi_error_sqlstate
És la paraula reservada SQLSTATE més un codi alfanumèric, vàlid per a SQL estàndard.
Exemple: SQLSTATE '23000' -- Clau duplicada
Un codi SQLSTATE equival a molts codis d'error de MySQL. Exemples:
| DESCRIPCIÓ ERROR | CODI MySQL | CODI SQLSTATE |
|---|---|---|
| Clau duplicada en taula | 1022 | '23000' |
| Columna no pot ser nula | 1048 | |
| Columna ambigua | 1052 | |
| Violació de clau aliena | 1216 | |
| ... | ... | |
| Taula desconeguda | 1051 | '42S02' |
| Taula inexistent | 1146 | |
| ... | ... | |
| Accés denegat a la BD | 1044 | '42000' |
| BD desconeguda | 1049 | |
| ... | ... |
Podem consultar els codis d'error de MySQL i SQLSTATE ací: https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
A més, SQLSTATE 'HY000' es pot usar com a codi d'error general.
4.2.3. nom_error
És un nom que li posem a l'error, el qual haurem declarat prèviament. A eixe nom d'error se li coneix com una "condició".
Exemple de condició: taula_desconeguda
La forma de declarar una condició és:
| SQL | |
|---|---|
O bé:
| SQL | |
|---|---|
4.2.4. SQLWARNING
És una abreviació per a tots els codis SQLSTATE que comencen per 01.
4.2.5. NOT FOUND
És una abreviació per a tots els SQLSTATE que comencen per 02.
Sol usar-se per a establir la condició de recórrer un cursor (ja ho vorem).
4.2.6. SQLEXCEPTION
És una abreviació per a tots els codis SQLSTATE que no són SQLWARNING ni NOT FOUND.
Nota
Els handlers s'han de definir després de les variables i condicions.
4.3. Exercicis de handlers
7. Volem fer inserts en la taula de jugadors, però de forma que si dóna algun error, que faça constància en algun lloc del moment on s'ha produït l'error i quin error. Per a fer això:
-
a) Crea una taula on es guardaran els errors:
-
b) Crear un procediment que faça les insercions en la taula de jugadors i, si cal, també en la taula d'errors:
- Passa-li com a paràmetres els valors que necessites per a inserir un jugador: codi d'equip, dorsal, nom, lloc i sou.
- Crea un handler per a que quan done l'error de clau duplicada, 1062, (degut a que ja existia el jugador) inserisca l'error "Jugador ja existeix".
- Crea un handler per a que quan done l'error de clau aliena, 1452, (degut a que l'equip del jugador no existeix) inserisca l'error "Equip inexistent".
- Fes l'insert en la taula de jugadors amb els valors passats com a paràmetre al procediment.
Notes
- Pensa si en este cas donaria igual declarar els handlers CONTINUE o EXIT.
- Data actual:
current_date. - Hora actual:
current_time.
-
c) Insereix, mitjançant crides a eixe procediment, diversos jugadors correctes (que no existisquen però sí que existisca l'equip), que no existisca l'equip o que ja existisca el jugador. Després mira el contingut de la taula d'errors per a comprovar si tot ha funcionat com s'esperava.