2. MYSQL E LE STORED PROCEDURES
Una frase che una volta si sentiva spesso.
“Bello MySQL! Peccato che non supporti le stored procedures… Se ce le avesse lo userei anch’io.”
Ma cosa sono le stored procedure? E perché tanti ne sentivano la mancanza?
Un esempio pratico collegato al database World, predefinito in MySQL.
DELIMITER //
CREATE PROCEDURE NumCittà (IN Lingua CHAR(30), OUT NumC
INTEGER)
BEGIN
SELECT COUNT(*) INTO NumC
FROM countrylanguage AS Cl, country AS Cn, City AS Cy
WHERE Cl.CountryCode = Cn.Code
AND Cy.CountryCode = Cn.Code
AND Cl.Language = Lingua;
END; //
DELIMITER ;
3. MYSQL E LE STORED PROCEDURES
Le istruzioni della slide precedente creano un procedura per la
base di dati World.
Questa procedura, una volta creata, può essere richiamata in
qualsiasi momento dal prompt dei comandi, attualizzando i suoi
parametri.
Es.
CALL NumCittà(“Inglese”,@Num);
SELECT @Num AS Città_Inglese;
In questo modo le istruzioni della Stored Procedure NumCittà
vengono eseguite assegnando al parametro di ingresso Lingua il
valore “Inglese”.
Il risultato dell’esecuzione viene reso disponibile nella variabile
@Num.
4. MYSQL E LE STORED PROCEDURES
Esaminiamo più nel dettaglio l’esempio appena
proposto.
DELIMITER //
Questa istruzione modifica l’indicatore di fine istruzione per
MySQL.
Di default il delimitatore è il carattere “;”.
All’interno di una stored procedure però sono presenti più
istruzioni, quindi perché MySQL interpreti correttamente
l’istruzione CREATE PROCEDURE occorre cambiare il
delimitatore.
Nel nostro caso si sceglie la combinazione “//”, ma
avremmo potuto scegliere qualsiasi altra combinazione di
caratteri
Al termine della stored procedure si ripristina il delimitatore
standard con l’istruzione:
DELIMITER ;
5. MYSQL E LE STORED PROCEDURES
CREATE PROCEDURE NumCittà (IN Lingua
CHAR(30), OUT NumC INTEGER)
L’intestazione della procedura consente di definire alcune
caratteristiche essenziali:
• Nome della procedura
Il nome della procedura servirà per richiamare la procedura stessa
dal prompt dei comandi di MySQL.
• Elenco dei parametri
I parametri indicano le informazioni che occorre fornire alla
procedura affinché questa possa essere eseguita, e quelle che la
procedura fornirà come risultato.
IN parametri di ingresso
OUT parametri di uscita
INOUT parametri bidirezionali
Nel nostro caso la procedura riceve in ingresso una stringa
Lingua e produce in uscita un numero intero NumC.
6. MYSQL E LE STORED PROCEDURES
BEGIN
...
END; //
Le due parole chiave BEGIN e END racchiudono il
corpo della funzione.
Come si vede l’istruzione CREATE PROCEDURE
termina con il delimitatore “//”
Il delimitatore “;” invece indica il termine di ogni
istruzione all’interno del corpo della procedura e il
termine del blocco BEGIN … END (non il termine
dell’istruzione CREATE)
7. MYSQL E LE STORED PROCEDURES
SELECT COUNT(*) INTO NumC
FROM countrylanguage AS Cl, country AS
Cn, City AS Cy
WHERE Cl.CountryCode = Cn.Code
AND Cy.CountryCode = Cn.Code
AND Cl.Language = Lingua;
Si tratta come si vede di una query normale
Ci sono però due particolari importanti:
• Il risultato della SELECT viene memorizzato nel
parametro di uscita NumC
• Il valore di Cl.Language viene ricavato dal parametro
di ingresso Lingua
In sostanza questa query determina in quante città si
parla una certa lingua
8. MYSQL E LE STORED PROCEDURES
CALL NumCittà(“Inglese”,@Num);
Con questa sintassi viene eseguita dal prompt dei
comandi di MySQL la procedura NumCittà
Al parametro lingua viene assegnato il valore
“Inglese”
Il risultato della query viene memorizzato nella variabile
@Num
SELECT @Num AS Città_Inglese;
Il valore della variabile @Num viene infine visualizzato
col nome Città_Inglese.
9. VARIABILI IN MYSQL
MySQL consente di memorizzare un valore in una
variabile definita dall’utente
Il valore può così essere utilizzato da istruzioni
successive a quelle in cui è stato assegnato alla
variabile
Le variabili sono associate alla connessione in cui
vengono create
Una variabile definita da un client non viene vista da un altro
client
Al termine della connessione vengono tutte eliminate
Nomi delle variabili
Iniziano con @
Possono contenere lettere e numeri
Possono contenere i caratteri “.”, “_” e “$”
10. VARIABILI IN MYSQL
Assegnamento di un valore a una variabile
SET @var_name = expr [, @var_name = expr] ...
Si può utilizzare anche il simbolo :=
SET @t1=1, @t2=2, @t3:=4;
SELECT @t1, @t2, @t3, @t4 := @t1+@t2+@t3;
+------+------+------+--------------------+
| @t1 | @t2 | @t3 | @t4 := @t1+@t2+@t3 |
+------+------+------+--------------------+
| 1 | 2 | 4 | 7 |
+------+------+------+--------------------+
All’interno della SELECT è obbligatorio utilizzare il simbolo :=
Non si deve mai assegnare un valore a una variabile e utilizzarlo
all’interno della stessa istruzione
MySQL non garantisce il risultato
Possono verificarsi effetti indesiderati
11. VARIABILI IN MYSQL
A una variabile si possono assegnare solo i seguenti tipi di dato
Numeri interi (INTEGER)
Numeri con a virgola fissa (DECIMAL)
Numeri a virgola mobile (FLOAT, DOUBLE)
Stringhe di caratteri
NULL
Tutti i tipi non ammessi vengono convertiti nei tipi ammessi
La conversione può essere forzata con l’istruzione CAST
SET @v1 = b'1000001';
SET @v2 = CAST(b'1000001' AS UNSIGNED), @v3 = b'1000001'+0;
SELECT @v1, @v2, @v3;
+------+------+------+
| @v1 | @v2 | @v3 |
+------+------+------+
| A | 65 | 65 |
+------+------+------+
12. VARIABILI IN MYSQL
Le variabili trovano il loro utilizzo nelle espressioni all’interno
delle query
Es.
SET @var = 15;
SELECT *
FROM Table AS T
WHERE T.Campo = @var;
Non possono essere utilizzate negli identificatori di campi e
tabelle, o al posto di parole chiave
Es. (non valido)
SET @var1 = ‘Table’;
SET @var2 = ‘SELECT’
@var2 *
FROM @var1 AS T
WHERE T.Campo = 15;
13. VARIABILI IN MYSQL
C’è una sola eccezione a questa regola
Si costruisce una query in una variabile stringa con l’istruzione PREPARE
La si esegue con l’istruzione EXECUTE
Es.
SET @c = "c1";
SET @s = CONCAT("SELECT ", @c, " FROM t");
PREPARE stmt FROM @s;
EXECUTE stmt;
+----+
| c1 |
+----+
| 0 |
+----+
| 1 |
+----+
2 rows in set (0.00 sec)
DEALLOCATE PREPARE stmt;
14. SINTASSI DI UNA STORED PROCEDURE
La sintassi generale di una stored procedure è la
seguente.
CREATE PROCEDURE nome ([<parametro>[,...]])
[SQL SECURITY { DEFINER | INVOKER }]
BEGIN
<istruzioni>
END; //
La sintassi di ciascun parametro è invece la seguente:
[ IN | OUT | INOUT ] <nome> <tipo>
15. DICHIARAZIONE DI VARIABILI
All’interno di una stored procedure è possibile
dichiarare variabili
DECLARE <nome> <tipo> [DEFAULT <valore>];
Si può assegnare valori alle variabili in due modi
SELECT <campo> INTO <variabile>
FROM ... ;
SET <variabile> = <espressione>;
Un particolare tipo di variabile sono i CURSORI
DECLARE <nome> CURSOR FOR <query> ;
16. LE VARIABILI CURSORI
Una variabile cursore serve per scorrere il risultato di una query caricandone i
record progressivamente all’interno di opportune variabili
DECLARE a INT;
DECLARE b CHAR(50);
DECLARE cur CURSOR FOR
SELECT id, nome
FROM clienti
WHERE cat = <parametro>;
OPEN cur;
FETCH cur INTO a, b;
CLOSE cur;
Quando viene aperto, il cursore si posiziona sulla prima tupla del risultato della
query
Ogni volta che si effettua un FETCH, la tupla viene caricata nelle variabili
specificate dopo la parola chiave INTO.
La chiusura del cursore non è obbligatoria. MySQL chiude automaticamente i
cursori al termine di una procedura.
17. LA STRUTTURA IF – THEN – ELSE
È possibile utilizzare una semplice struttura di
selezione
La sintassi è la seguente
IF <condizione> THEN
<istruzioni>
ELSE
<istruzioni>
END IF;
Come sempre la parte ELSE è facoltativa
18. LA STRUTTURA DI ITERAZIONE LOOP
Si tratta di un semplice costrutto per cicli illimitati
Sintassi:
<etichetta>: LOOP
<istruzioni>
END LOOP <etichetta>;
Per uscire dal ciclo:
LEAVE <etichetta>;
Per passare all’iterazione successiva:
ITERATE <etichetta>;
19. LA STRUTTURA DI ITERAZIONE LOOP
Es.
DELIMITER //
CREATE PROCEDURE SommaInt(IN p1 INT, OUT Sum INT)
BEGIN
DECLARE i INT;
SET Sum = 0;
SET i = 0;
label1: LOOP
SET i = i + 1;
SET Sum = Sum + i;
IF i < p1 THEN
ITERATE label1;
END IF;
LEAVE label1;
END LOOP label1;
END; //
DELIMITER ;
20. LA STRUTTURA DI ITERAZIONE REPEAT
Si tratta di un semplice costrutto per cicli limitati
Sintassi:
<etichetta>: REPEAT
<istruzioni>
UNTIL <condizione>
END REPEAT <etichetta>;
Il ciclo si interrompe quando la condizione diventa vera
per la prima volta
La condizione viene valutata al termine di ogni
iterazione
21. LA STRUTTURA DI ITERAZIONE REPEAT
Es.
DELIMITER //
CREATE PROCEDURE SommaInt(IN p1 INT, OUT Sum INT)
BEGIN
DECLARE n INT;
SET n = 0;
SET Sum = 0;
REPEAT
SET n = n + 1;
SET Sum = Sum + n;
UNTIL n = p1
END REPEAT;
END; //
CALL SommaInt(10,@Somma) //
SELECT @Somma //
+------+
| @x |
+------+
| 55 |
+------+
1 row in set (0.00 sec)
22. LA STRUTTURA DI ITERAZIONE WHILE
Si tratta di un semplice costrutto per cicli limitati
Sintassi:
<etichetta>: WHILE <condizione> DO
<istruzioni>
END WHILE <etichetta>;
Il ciclo si interrompe quando la condizione diventa
falsa per la prima volta
La condizione viene valutata prima di ogni
iterazione
23. LA STRUTTURA DI ITERAZIONE WHILE
Es.
DELIMITER //
CREATE PROCEDURE SommaInt(IN p1 INT, OUT Sum
INT)
BEGIN
DECLARE i INT;
SET Sum = 0;
SET i = 0;
label1: WHILE i <= p1 DO
SET i = i + 1;
SET Sum = Sum + i;
END WHILE label1;
END; //
DELIMITER ;
24. DICHIARAZIONE DI HANDLER
Handler: gruppo di istruzioni da eseguire al verificarsi di
particolari condizioni durante l’esecuzione di una procedura
Sintassi:
DECLARE <azione> HANDLER
FOR <condizione1> [, <condizione2>] ...
<istruzioni>;
Azioni
EXIT Termina la procedura
CONTINUE Continua l’esecuzione
Condizioni
<codice_errore_MySQL>
SQLSTATE [VALUE] <valore>
SQLWARNING
NOT FOUND
SQLEXCEPTION
25. CONDIZIONI PER GLI HANDLER
<codice_errore_MySQL> e SQLSTATE
Elenco dei codici di errore e SQLSTATE di MySQL
SQLWARNING
Tutti i codici di errore che cominciano per ‘01’
NOT FOUND
Tutti i codici di errore che cominciano per ‘02’
SQLEXCEPTION
Tutti i codici di errore che NON cominciano per ‘00’, ‘01’, ‘02’
I codici che cominciano con ‘00’ non indicano un errore ma
l’esecuzione corretta di un’operazione, e quindi non
andrebbero mai utilizzati in un Handler
26. STORED FUNCTIONS
Simili alle Stored Procedures ma più semplici
Restituiscono un dato semplice
Non possono restituire un insieme di tuple
Esempi di Stored Functions predefinite sono le funzioni di aggregazione
Sintassi:
CREATE FUNCTION <nome>([<parametro>[,...]])
RETURNS <tipo>
[SQL SECURITY { DEFINER | INVOKER }]
BEGIN
<istruzioni>
END;
Parametri
<parametro> <tipo>
27. SQL SECURITY
Per eseguire una qualsiasi istruzione su una base di dati
è necessario che l’utente possieda i privilegi necessari
Per esempio non è detto che un utente abbia il permesso di
inserire tuple in una tabella, oppure di cancellarle
La clausola SQL SECURITY permette di specificare chi
deve possedere i privilegi necessari a eseguire tutte le
istruzioni contenute in una stored procedure
DEFINER Chi ha creato la procedura deve
possedere i permessi necessari a eseguirla
INVOKER Chi invoca la procedura deve possedere i
permessi necessari a eseguirla