Upload
matteo-ceserani
View
64
Download
2
Embed Size (px)
Citation preview
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 NumCINTEGER)
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 ;
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.
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 ;
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.
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)
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
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.
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 “$”
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
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 |
+------+------+------+
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;
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;
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>
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> ;
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 dellaquery
Ogni volta che si effettua un FETCH, la tupla viene caricata nelle variabilispecificate dopo la parola chiave INTO.
La chiusura del cursore non è obbligatoria. MySQL chiude automaticamente i cursori al termine di una procedura.
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
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>;
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 ;
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 veraper la prima volta
La condizione viene valutata al termine di ogniiterazione
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)
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 diventafalsa per la prima volta
La condizione viene valutata prima di ogniiterazione
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 ;
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
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
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>
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