2. Tipus i paràmetres dels procediments emmagatzemats
2.1. Tipus de rutines
Hi ha dos tipus de rutines:
- Procediments (procedures)
- Funcions (functions)
Un procediment és un conjunt de tasques o accions que no retornen res a l'usuari; en canvi, les funcions retornen un valor. Igual que en qualsevol llenguatge de programació, la crida també serà diferent, ja que les funcions han d'arreplegar eixe valor.
2.1.1. Procediments
Veiem les parts més comunes amb un exemple. Suposem que tenim una base de dades amb una taula d'articles i volem un procediment per a que incremente el preu d'un article.
El delimitador
Com el punt i coma (;) executa ja la sentència, abans de crear els procediments (o funcions) hem de dir que el delimitador de sentències és un altre (//).
Parts del procediment
CREATE PROCEDUREper a crear el procediment iBEGINiENDper a delimitar el cos.- Nom del procediment:
incr_preu. - Definició de cada paràmetre: nom i tipus →
(art CHAR(10), incr FLOAT). DECLAREper a declarar variables locals.SETper a assignar valors a variables. Les variables amb@són globals i no s'han de declarar.SELECT ... INTOposa el resultat de la SELECT en una variable.- Acabem la sentència amb el nou delimitador:
//. - Si volem, tornem a dir que el delimitador és
;.
Per a fer la crida a este procediment:
CALLés la sentència per a invocar l'execució del procediment.SELECT @trobatés per si volem consultar el valor de la variable global modificada pel procediment.
És a dir: el client de la BD només ha de saber el nom del procediment i quins valors ha de passar com a paràmetre. No té per què saber ni el nom de la taula ni els noms dels camps.
Ara bé, com hem vist, si volem consultar si el procediment ha trobat o no l'article, també haurà de conéixer el nom de la variable global que modifica el procediment. Per això serà convenient que, en compte d'un procediment, usem una funció que retorne eixe valor.
Per a esborrar un procediment:
| SQL | |
|---|---|
2.1.2. Funcions
Veiem les parts principals amb un altre exemple. En una BD de futbol, on tenim en la taula de partits els gols que ha marcat cada equip en cada partit, volem una funció que ens retorne quants partits ha guanyat cada equip.
| SQL | |
|---|---|
Parts de la funció
CREATE FUNCTIONper a crear la funció.- El
RETURNSés per a indicar el tipus del valor que retorna la funció. - El
BEGIN-ENDno caldria si el cos de la funció només tinguera 1 instrucció: elRETURN. Igual amb els procediments. - Amb
RETURNretornarem al client el valor calculat.
Error 1418
Potser done este error en funcions amb INSERT/UPDATE/DELETE:
Error Code: 1418. This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
Possibles solucions:
- a) Executa en la consola de MySQL:
SET GLOBAL log_bin_trust_function_creators = 1; - b) Afig açò al fitxer de configuració
mysql.ini:log_bin_trust_function_creators = 1;
Per a fer la crida a una funció no es fa amb el CALL. En compte d'això, com la funció retorna un valor, la crida ha d'estar dins d'una expressió que arreplegue eixe valor.
Per tant, la crida es pot donar en diferents contextos (sempre formant part d'una expressió). Exemples de crides:
a) Mostrar els partits guanyats pel Barça:
| SQL | |
|---|---|
b) Guardar en una variable el valor retornat per a després usar-la com siga:
c) Mostrar (entre altres coses) els partits guanyats per l'equip de cada jugador i/o posar-los en una condició:
d) Incrementar 1000 euros a cada jugador per cada partit que ha guanyat el seu equip:
Per a esborrar una funció:
| SQL | |
|---|---|
2.2. Paràmetres i variables
2.2.1. Declaració de paràmetres
En les funcions tots els paràmetres són d'entrada. Però en la definició dels procediments podem indicar si són d'entrada, d'eixida, o d'entrada i eixida. Posarem davant de cada paràmetre:
IN: Paràmetre d'entrada. En el moment de cridar al procediment, s'ha de donar este valor. És l'opció per defecte.OUT: Paràmetre de sortida. Quan es fa la crida al procediment, en eixe paràmetre es passa una variable, sense cap valor en concret (mai una constant). El procediment assignarà un valor a eixe paràmetre, de forma que podrà ser consultat després de fer la crida al procediment. Per exemple:
INOUT: Paràmetre d'entrada i de sortida.
Recorda
Només podem usar paràmetres d'eixida en els procediments (no en les funcions).
Sobre els noms de les variables
- Si en una SELECT/UPDATE hi ha també variables, en cas d'ambigüitat de noms, MySQL agafa la variable (no la columna). Si volem que agafe la columna cal usar el nom qualificat (
taula.columna), o bé posar un nom diferent a la variable (v_arten lloc deart, per exemple). - El nom de les variables en MySQL no és case sensitive. És a dir, es considera la mateixa variable:
preu,Preu,PREU...
2.2.2. Declaració de variables locals
L'àmbit de visibilitat estarà només entre el BEGIN i END on està declarada la variable.
Sintaxi:
| SQL | |
|---|---|
- Sempre es declaren just a continuació del
BEGINd'un PE. - En cada sentència
DECLAREes poden declarar diverses variables, però sempre del mateix tipus i mateix valor inicial (DEFAULT). Si necessitàrem diferents tipus de variable o diferents valors inicials, haurem de posar diferents sentènciesDECLARE.
Exemples:
| SQL | |
|---|---|
2.2.3. Variables globals (variables de sessió)
- L'àmbit de visibilitat és en qualsevol lloc de la connexió. El valor de les variables globals es guarda mentre està activa la connexió a la BD.
- És l'única forma d'usar variables des de fora d'un PE.
- No s'aconsella el seu ús dins dels PE.
- No es declaren: simplement s'indica el nom de la variable que volem usar amb el signe
@davant:@nom_var.
Exemples:
2.2.4. Assignar valor a les variables
- Amb
SET(ja ho hem vist abans):
| SQL | |
|---|---|
- Amb
SELECT ... INTO:
Si la SELECT retornara més d'una fila de resultats, donaria error.
- Invocant una funció o procediment amb paràmetres definits com a
OUToINOUT:
| SQL | |
|---|---|
2.3. Exercicis de procediments i funcions
Exercicis sense sentències de control de flux (BD futbol)
1. Fes la funció maxGolejador que li passes com a paràmetre un equip i retorna el dorsal del golejador d'eixe equip que més gols ha marcat. A continuació fes les següents crides per a:
- a) Mostrar per pantalla el dorsal que més gols ha marcat del Barça (codi 'bar').
- b) Mostrar el dorsal que més gols ha marcat de cada equip.
- c) Mostrar el nom del golejador que més gols ha marcat de cada equip.
- d) Incrementar 10000 euros als jugadors que més gols han marcat en el seu equip.
2. Fes el procediment marcar, que li passes com a paràmetre un jugador (és a dir: codi d'equip i dorsal) i un partit (és a dir: equip de casa i de fora) i incremente en 1 els gols d'eixe golejador i també que incremente en 1 gol el resultat d'eixe partit. El procediment ha de retornar el nou resultat del partit (gols de casa i gols de fora). A continuació:
- a) Fes la crida per a dir que ha marcat el dorsal 10 del Barça en el Barça-València (sabent que el codi del Barça és 'bar' i el del València és 'val').
- b) Mostra per pantalla el resultat del partit (amb els valors retornats abans).