Le stored procedures ci permettono di memorizzare all'interno dei nostri database dei veri e propri sotto-programmi destinati ad essere richiamati per l'esecuzione di determinate operazioni; esse contengono i comandi SQL che dovranno essere eseguiti, in questo modo non sarà necessario riscriverli ogni volta che si deve inviare al DBMS una determinata interrogazione.
Nelle stored procedures acquisiscono una particolare importanza i costrutti per il controllo del flusso dei dati; grazie ad essi sarà infatti possibile inserire delle condizioni sulla base dei diversi eventi che potranno verificarsi durante il trattamento dei dati, rendendo i nostri sub-programmi ancora più raffinati. In questo breve articolo vedremo come utilizzare i costrutti per il flow control e quali elementi entrano in gioco durante l'introduzione delle condizioni.
Le variabili
Le variabili, molto utilizzate nei linguaggi di programmazione e di scripting, sono dei veri e propri "contenitori di informazioni"; ad esse potrà essere associato un valore e la variabile diventerà rappresentazione di quest'ultimo.
Vediamo un semplice esempio di definizione di una varabile all'interno di una procedura:
CREATE PROCEDURE p () BEGIN DECLARE x INT; DECLARE y INT; SET x = 8; SET y = 8; INSERT INTO tbl VALUES (x); SELECT field * x FROM tbl WHERE field >= y; END; //
La procedura del nostro esempio non accetta come argomento la definizione di una variabile, all'interno delle parentesi tonde non viene infatti passato alcun argomento; vengono invece definite due variabili (x
ed y
) all'interno del blocco di istruzioni BEGIN
/ END
e ad esse viene associato un tipo di dato e un valore.
I nomi delle variabili e il tipo di dato ad esse associato vengono introdotti tramite il comando DECLARE
, mentre abbiamo utilizzato SET
per stabilire quale valore dovesse essere associato alle variabili.
Una volta definite le varabili queste sono state utilizzate per l'esecuzione di due differenti istruzioni, un comando per l'inserimento e una query di selezione.
Nel comando per l'INSERT
la variabile x
rappresenta il valore 8
ad essa associato; stesso discorso per quanto riguarda il valore y
usato come argomento per il confronto nella clausola WHERE
della SELECT
.
La possibilità di definire delle variabili assume un ruolo particolarmente importante in quanto una volta che esse vengono dichiarate è possibile riutilizzarle in qualunque momento tramite una semplice operazione di chiamata della procedura che vedremo tra poco.
Alle variabili è possibile associare anche un valore di default grazie all'utilizzo della clausola omonima; quindi una procedura come quella creata nel nostro primo esempio avrebbe potuto essere definita anche in questo modo:
CREATE PROCEDURE p () BEGIN DECLARE x, y INT DEFAULT 8; INSERT INTO tbl VALUES (x); SELECT field * x FROM tbl WHERE field >= y; END; //
Nonostante questa seconda procedura sia concettualmente identica alla prima, possiamo notare un importante elemento di novità: due variabili sono state definite tramite un unico comando DECLARE
e ad esse è stato associato un valore di default valido per entrambe.
Indipendentemente dall'utilizzo o meno di valori di default, la procedura definita potrà essere richiamata semplicemente facendo riferimento al suo nome utilizzato come argomento del comando CALL
:
mysql> CALL p () //
Il risultato sarà quindi determinato dal valore del field
, unico elemento suscettibile di variazione, in quanto conosciamo a priori il valore delle due variabili definite.
Utilizzo delle condizioni all'interno delle procedure
Ora che sappiamo come definire le variabili, vediamo come è possibile utilizzarle all'interno di costrutti per il controllo del flusso; le variabili assumo un ruolo molto importante in questo tipo di istruzioni, infatti le condizioni possono basarsi proprio sul valore assunto da esse influenzando il manifestarsi degli eventi. Facciamo un esempio:
CREATE PROCEDURE p (IN par INT) BEGIN DECLARE var INT; SET var = par + 1; IF var = 0 THEN INSERT INTO tbl VALUES (10); END IF; IF par = 0 THEN UPDATE tbl SET field = field + 1; ELSE UPDATE tbl SET field = field + 2; END IF; END; //
Chi ha già una certa conoscenza in merito ai linguaggi di programmazione e di scripting non avrà certo difficoltà a comprendere i meccanismi messi in atto dalla procedura mostrata che riassumiamo in questo elenco:
- Viene creata la procedura, nel nostro caso denominata semplicemente
p
par
IN
- Viene inserito il delimitatore iniziale del blocco di istruzioni (
BEGIN
1
- Viene introdotta l'istruzione condizionale
IF
0
IF var = 0
THEN
INSERT
10
THEN
IF
- Il primo blocco di condizione viene quindi chiuso tramite il delimitatore
END IF
- Infatti, viene inserito un secondo blocco di condizione: esso stabilisce che se il valore del parametro è pari a
0
UPDATE
field
- Diversamente (
ELSE
1
2
ELSE
IF
ELSE
- A questo punto, può essere chiuso sia il secondo blocco di condizione, che l'intero blocco di istruzioni del sotto-programma.
In questo caso, a differenza delle procedure per la dichiarazione delle variabili descritte nei primi due esempi, il nostro sotto-programma p
mysql> call p (n) //
Il valore di questo parametro avrà un ruolo fondamentale nella soddisfazione o meno delle condizioni definite all'interno del blocco.
Flow control con CASE e WHEN
Oltre ai blocchi condizionali basati su IF
abbiamo un'altra tipologia di costrutti per il controllo del flusso che può essere impiegata nella creazione di stored procedures. Si tratta delle istruzioni basate sulle clausole CASE
e WHEN
; vediamone subito un semplice esempio:
CREATE PROCEDURE p (IN par INT) BEGIN DECLARE var INT; SET var = par + 1; CASE var WHEN 0 THEN INSERT INTO tbl VALUES (10); WHEN 1 THEN INSERT INTO tbl VALUES (11); ELSE INSERT INTO tbl VALUES (12); END CASE; END; //
La logica alla base di questa routine non è molto differente da quella presentata nell'esempio precedente; vediamone nel particolare i singoli elementi costituivi:
- Abbiamo creato innanzitutto una procedura chiamata
p
IN
- Una volta definito il nome della procedura e il relativo argomento, siamo passati alla delimitazione del blocco di istruzioni tramite
BEGIN
DECLARE
CASE
Select…
Case
Switch()
IF
CASE
- Nella routine abbiamo stabilito che
CASE
- A questo punto entra in gioco
WHEN
THEN
ELSE
var
CASE
- Stabilite le istruzioni di condizione abbiamo chiuso il blocco
CASE
END CASE
Osservando quanto esposto nel nostro esempio possiamo isolare il codice relativo al blocco CASE
:
CASE var WHEN 0 THEN INSERT INTO tbl VALUES (10); WHEN 1 THEN INSERT INTO tbl VALUES (11); ELSE INSERT INTO tbl VALUES (12); END CASE;
In pratica l'istruzione comunica al Database Manager che il termine di paragone è il valore di var
, quando (WHEN
) questo valore è pari a 0
allora (THEN
) l'inserimento dovrà essere pari a 10
; quando esso è pari a 1
avremo un VALUE
uguale a 11
; diversamente (ELSE
) l'inserimento sarà pari a 12
per tutti i valori di var
diversi da 0
e 1
.
Conclusioni
In questa breve guida ci siamo occupati dell'utilizzo dei costrutti per il controllo del flusso di dati nelle Stored Procedures; per far questo abbiamo introdotto l'argomento relativo alle variabili passando poi al loro utilizzo all'interno dei blocchi di condizione. Questo discorso potrà essere ampliato con una trattazione riguardante l'utilizzo dei "cicli" nelle routines, argomento che approfondiremo in una prossima trattazione.