Sie sind auf Seite 1von 21

Procdure stocke

Par Draeli
www.siteduzero.com
Licence Creative Commons 6 2.0
Dernire mise jour le 6/12/2012
Sommaire
2 Sommaire ...........................................................................................................................................
3 Procdure stocke .............................................................................................................................
3 Procdures stockes : les bases ......................................................................................................................................
3 Cration d'une procdure ............................................................................................................................................................................................
5 Appel d'une procdure ................................................................................................................................................................................................
6 Supprimer une procdure ............................................................................................................................................................................................
6 Voir les procdures existantes ....................................................................................................................................................................................
8 Les blocs d'instructions .....................................................................................................................................................
9 Dclaration : variable, gestionnaire, curseur .....................................................................................................................
9 Variables ......................................................................................................................................................................................................................
10 Gestionnaire ..............................................................................................................................................................................................................
13 Curseur ......................................................................................................................................................................................................................
15 Instructions de contrle ...................................................................................................................................................
15 IF ...............................................................................................................................................................................................................................
16 CASE .........................................................................................................................................................................................................................
17 LOOP ........................................................................................................................................................................................................................
18 REPEAT ....................................................................................................................................................................................................................
18 WHILE .......................................................................................................................................................................................................................
19 ITERATE ...................................................................................................................................................................................................................
20 Exemples .........................................................................................................................................................................
21 Partager .....................................................................................................................................................................................................................
2/22
www.siteduzero.com
Procdure stocke
Par Draeli
Mise jour : 06/12/2012
Difficult : Intermdiaire
618 visites depuis 7 jours, class 194/797
Vous avez vu la premire partie : les requtes prpares et vous avez ador : alors vous allez aimer a.
Les procdures stockes, apparues avec MySQL 5, sont ce que la cafine est au caf, on peut boire le caf sans, mais a ne
serait pas aussi bon.
Cette partie de MySQL, qui n'est encore que trop peu utilise, est un bon moyen de mettre en oeuvre des scripts avancs qui,
non content de pouvoir faire tout un tas d'actions, permettent une optimisation des scripts, ventuellement une couche
d'abstraction supplmentaire pour la programmation et, plus basiquement, des requtes qui sans cela seraient complexes et
lourdes mettre en oeuvre, voire impossibles.
C'est donc en partant de ce constat que je vais m'efforcer de vous montrer tous ces points et bien plus ...
Pr-requis :
- MySQL 5.0 ou Suprieur
- avoir des connaissances de base sur MySQL est recommand (savoir faire des SELECT, UPDATE, INSERT, DELETE)
- des bases en algorithme pour faire vos propres scripts par la suite
- savoir utiliser MySQL en ligne de commande pour pouvoir effectuer les exercices.
Sommaire du tutoriel :
Procdures stockes : les bases
Les blocs d'instructions
Dclaration : variable, gestionnaire, curseur
Instructions de contrle
Exemples
Procdures stockes : les bases
Cration d'une procdure
La syntaxe est relativement simple et se prsente sous la forme suivante :
Code : SQL
CREATE PROCEDURE nom_de_la_procedure([parametres])
Le nommage respecte les rgles habituelles, imaginons donc une procdure nomme 'sdz', elle sera cre sous la forme :
Code : SQL
CREATE PROCEDURE sdz() caracteristiques
Sommaire 3/22
www.siteduzero.com
Rien de compliqu jusque l, mais le point le plus important concerne les paramtres qui se dcomposent en trois parties.
sens_du_parametre nom_parametre type_parametre
Le sens du parametre peut prendre 3 valeurs :
IN : le paramtre sera une valeur ou une variable d'entre. Le paramtre indiqu peut tre une valeur ou une variable que vous
envoyez lors de l'appel, et qui sera utilis l'intrieur de la procdure.
OUT : le paramtre sera une variable de sortie. Le paramtre indiqu sera une variable (de session ou de procdure) qui prendra
une valeur (enfin normalement, sinon a n'a que peu d'intrt) lors de la procdure.
INOUT : le paramtre sera une variable d'entre-sortie. Cette variable pourra tre utilis ou non dans la procdure, et verra
normalement sa valeur modifie lors de la procdure.
Le nom_parametre suit les rgles de nommage habituel. Ce nom de paramtre reprsentera par la suite dans la procdure une
variable qui aura pour valeur celle qu'on lui aura assign.
Si vous ne comprenez pas ce que a veut dire, ce n'est pas grave, les exemples ci-dessous sont l pour a.
Le type_parametre prend en valeur le type de la valeur ou de variable attendu.
Avant de passer la pratique, rappelons un point important : les procdures stockes sont, comme leur nom l'indique, stockes...
J'entends dj des "on s'en serait dout". En fait, s'il est vrai qu'elles le sont, ceci entrane plusieurs choses importantes et qui
font toute la puissance des procdures stockes. De par ce statut, elles sont tout moment utilisables ; ainsi, les dclarer une
fois pour une base de donnes suffit pour pouvoir les utiliser par la suite tout moment. Contrairement aux requtes prpares,
elles ne dpendent pas d'un thread et ne sont pas dtruites automatiquement ; de mme, elles restent prsentes si le serveur
s'arrte.
Ceux disposant de MySQL Query Browser pourront par la suite vrifier cet tat de fait en ouvrant la base qu'ils ont utilise, et
verront apparatre en dessous des tables, de nouvelles icnes qui, sur leur ct, porte le nom de la procdure concerne.
Passons maintenant aux exemples .
Pour commencer, nous allons changer le dlimiteur de fin de requte utilis, ceci non pas afin de vous perturber mais tous
simplement par commodit pour la suite. Pour ce faire, tapez ceci en ligne de commande :
Code : SQL
DELIMITER |
Dsormais, quand vous terminerez une requte, il ne faudra plus faire ; mais |.
Premire procdure
Nous allons crer une procdure qui nous renvoie la valeur que nous lui avons passe en paramtre.
Code : SQL
CREATE PROCEDURE sdz(IN valeur VARCHAR(20))
BEGIN
SELECT valeur;
END|
Ceci est la structure complte d'une procdure : comme vous le voyez, ici apparaissent des choses dont je n'ai pas encore parl :
BEGIN et END, qui permettent de mettre plusieurs instructions l?intrieur. Et chaque instruction l?intrieur de ce bloc se
termine bien par ;, qui n'est en rien une erreur car si nous avions laiss notre dlimiteur normal, alors a n'aurait pas march. Pour
ceux qui ne me croient pas, je les invite remettre le dlimiteur ; normal en faisant :
Code : SQL
DELIMITER ;
et ressayer.
Dans ce bloc, nous voyons une instruction qui va chercher la valeur que nous avons passe en paramtre d'entre, et qui a t
stocke dans la variable 'valeur'.
Procdure stocke 4/22
www.siteduzero.com
Voil : vous avez fait votre premire procdure, combien simpliste.
Appel d'une procdure
Nous avons vu dans la partie prcdente comment crer une procdure, nous allons apprendre dsormais l'appeler.
Pour cela rien de plus simple, tapez :
Code : SQL
CALL sdz(2)|
Si avez toujours le dlimiteur |, vous ne devriez pas avoir de problme et en suivant les tapes depuis le dbut, vous aurez le
rsultat suivant :
Remarquez qu'ici l'appel est relativement simple, on peux complexifier la chose en partant du principe que notre valeur est dans
une variable : pour ce faire, on va dclarer une nouvelle variable '@a', laquelle on affectera une valeur :
Code : SQL
SET @a:=666|
Notre variable de session vaut donc dsormais 666.
Bien ! Appelons notre procdure avec cette variable :
Code : SQL
CALL sdz(@a)|
et la valeur qui va s'afficher est notre 666.
Tu ne nous avais pas dit qu'il existait autre chose que IN ?
Absolument, et maintenant que vous avez vu le principe de base, nous allons refaire une procdure mais qui elle prendra en plus
un paramtre de sortie. Pour l'occasion, on va faire un truc plus utile que prcdemment.
Calculons le carr d'un nombre :
Code : SQL
CREATE PROCEDURE carre(IN valeur INT, OUT toto BIGINT)
BEGIN
SELECT valeur*valeur INTO toto;
END|
En plus, on a un deuxime paramtre qui recevra une variable qui servira pour la sortie, de type BIGINT.
Procdure stocke 5/22
www.siteduzero.com
Dans le bloc d'instructions, on a une requte qui prend la valeur d'entre, la multiplie par elle-mme et le INTO va permettre de
dire "stocke-moi le rsultat ici", qui sera alors mis dans la variable locale 'toto'. Cette variable n'est pas accessible en dehors.
Ouais : donc le rsultat, on le rcupre comment ?
Ah vous allez voir, c'est simple.
On appelle la procdure que l'on vient de crer comme ceci :
Code : SQL
CALL carre(2,@b)|
L, on demande de calculer le carr de 2 en passant 2 la valeur d'entre, et on indique la variable '@b' qui stockera le rsultat
pour la sortie : remarquez que cette variable est, dans ce cas-ci, globale la session (ce qui veut dire qu'une autre session peut
trs bien appeler la mme procdure sans que les rsultats ne s'crasent : donc, chaque rsultat est li la session).
J'ai fait comme toi mais il ne se passe rien...
En fait c'est normal, la vraie magie c'est maintenant :
Code : SQL
SELECT @b|
La requte retourne le rsultat du calcul, c'est--dire : 4.
Si vous avez tout compris jusque l, alors rendez-vous la suite.
Supprimer une procdure
Certainement la partie la plus courte du tutoriel. vous venez de crer deux procdures dans les parties prcdentes, bien : nous
allons supprimer la premire qui ne sert strictement rien.
Code : SQL
DROP PROCEDURE sdz|
vous venez de supprimer votre procdure. Eh oui, c'est dj fini...
| vaut ; si vous avez lanc une autre fentre ou relanc la fentre des parties prcdentes.
Voir les procdures existantes
Vous souhaiterez certainement savoir par la suite comment lister les procdures que vous avez cres : pour cela, rien de plus
simple. Si vous voulez voir TOUTES les procdures de toutes les BDDs auxquelles vous avez un accs, alors :
Code : SQL
SHOW PROCEDURE STATUS LIKE '%%'\G
Remarquez dans ce cas que j'ai utilis '%%' pour indiquer que je veux toutes les procdures (rien ne vous empche de mettre
une expression qui corresponde plus vos besoins) et \G comme dlimiteur de fin de requte pour avoir un affichage lisible
humainement en ligne de commande.
Procdure stocke 6/22
www.siteduzero.com
Vous remarquerez certainement le paramtre Security_type dont je n'ai pas encore parl : sachez qu'il peut tre intressant pour
vous de le connatre tout comme la ligne : Definer, mais j'y reviendrai plus tard.
Avant de passer la suite, je tiens signaler que le LIKE '%%' n'est pas obligatoire dans ce cas, vous aurez le mme affichage
sans.
Affichage de la structure des procdures
Il est possible que vous ayez envie de voir quoi ressemble votre procdure une fois que vous l'aurez cre : pour cela, faites :
Code : SQL
SHOW CREATE PROCEDURE nom_procedure \G
Vous devez connatre le nom de la procdure, et celle-ci doit se trouver dans la base de donnes courante : si vous essayer
d'appeler une procdure (que vous auriez vue par exemple grce la requte donne en dbut de cette partie) qui se trouve dans
une autre base, vous aurez une erreur vous signalant que la procdure n'existe pas.
Procdure stocke 7/22
www.siteduzero.com
Ceci parat relativement logique dans la mesure o chaque base de donnes peut avoir des procdures qui, dans ce cas, auront
des noms communs.
Comme vous le remarquez, le code de la procdure apparat avec d'autres renseignements.
Les blocs d'instructions
Comme nous l'avons vu dans les parties prcdentes, les blocs d'instructions permettent de dlimiter une zone d'instructions ;
cependant, pour les autres parties du tuto, vous aurez besoin de comprendre son fonctionnement afin de ne pas vous arracher
les cheveux.
La syntaxe que nous avons vue prcdemment est la plus simple, savoir un BEGIN pour signaler le dbut, un END pour
signaler la fin et l'instruction de fin de requte derrire le END pour fermer le bloc.
Cependant, pour la suite, vous aurez peut-tre besoin d'attribuer un nom au bloc fermer ; pour ce faire, vous devez dclarer un
label, ou si vous prfrez, un nom pour le bloc.
Exemple :
Code : SQL
sdz_label: BEGIN
# ici les instructions
END sdz_label;
Remarquez que le label de fin doit tre le mme que pour celui du dbut.
Maintenant voyons le comportement des variables locales dans un bloc. Cette variable locale (dclare dans une procdure, j'y
reviendrai) a une 'dure de vie' et une 'visibilit'. Ces deux notions - ne pas confondre- sont ce qui est souvent source d'erreur.
Dure de vie : la variable existe de sa dclaration jusqu' la fin du bloc la contenant.
Visibilit : espace o la variable peut tre utilise. La variable est visible jusqu' la fin du bloc et passe invisible ds qu'un
nouveau bloc commence et ce, jusqu' ce que le dit bloc se finisse.
Voici un petit schma qui rendra les choses plus claires :
Enfin, on va faire un exemple qui permettra de lever d'ventuels doutes :
Code : SQL
CREATE PROCEDURE visibilite()
Procdure stocke 8/22
www.siteduzero.com
BEGIN
DECLARE var INT DEFAULT 1;
SELECT var AS 'Je suis la variable var du bloc 1';

BEGIN
DECLARE var INT DEFAULT 5;
SELECT var AS 'Je suis la variable du bloc 2';
SET var=10;
SELECT var AS 'Je suis la variable du bloc aprs
modification';
END;
SELECT var AS 'Je suis toujours la variable du bloc 1';
END;
Et on appelle ceci avec :
Code : SQL
call visibilite();
Ce qui donne le rsultat suivant :
Dclaration : variable, gestionnaire, curseur
Variables
Lors d'une procdure, il est possible de dclarer des variables qui seront locales la procdure, comme nous l'avons dans la
partie prcdente ; ces variables ont une dure de vie et une visibilit dont le schma suivant est le rcapitulatif :
Procdure stocke 9/22
www.siteduzero.com
Pour crer une variable il faut utiliser la syntaxe :
Code : SQL
DECLARE nom_variable type_variable;
Cependant ceci ne suffit pas : la dclaration des variables doit tre faite imprativement derrire la dclaration du bloc, donc
derrire BEGIN.
Exemple :
Code : SQL
CREATE PROCEDURE calcul1()
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE j FLOAT DEFAULT PI() ;

SELECT i + j;
END|
Dans les procdures, il est tout fait possible de mlanger les types de variables diffrentes, et mmes de les utiliser dans les
requtes.
De mme, les variables ont des espaces de noms diffrents ; il est donc tout fait possible d'avoir ceci :
Code : SQL
CREATE procedure toto()
BEGIN
declare a int DEFAULT 1;
SET @a:=2;
SELECT a,@a;
END|
Dans ce cas, les variables ont un nom identique, mais la premire est une variable locale la procdure et l'autre, une variable
globale la session.
Procdure stocke 10/22
www.siteduzero.com
Gestionnaire
Lorsque vous crirez des procdures, vous pourrez tre confronts des problmes de la forme suivante : "et l, si je mets une
valeur qui est dj dans la base de donnes, comment faire pour que la procdure continue sans s?arrter ?".
C'est un exemple de problme qui ne peut se grer qu'avec la dclaration d'un gestionnaire, qui permettra de dire au programme :
"continue d'excuter la procdure et tais-toi", fort pratique pour viter le comportement par dfaut qui, lors d'une rencontre
avec une erreur, sortira (EXIT) directement de la procdure.
Exemple :
Code : SQL
CREATE TABLE t (s1 int,PRIMARY KEY (s1))|
CREATE PROCEDURE erreur_continue ()
BEGIN
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'ERREUR';
SELECT 'je suis 1';
INSERT INTO t VALUES (1);
SELECT 'je suis 2';
INSERT INTO t VALUES (1);
SELECT 'je suis 3';
END;
|
Cet exemple, inspir du manuel mais corrig, essaie de mettre deux valeurs dans une table t ; seulement lors du deuxime appel,
une erreur de cl duplique sera gnre dans ce cas-l si nous n'avions pas la ligne :
Code : SQL
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'ERREUR';
Le code s'arrterait l et la ligne :
Code : SQL
SET @x = 3;
ne serait pas excute, ce qui n'est pas trs pratique.
Ouais, mais alors, comment on fait ?
Vous allez voir, c'est pas trop compliqu : pour cela, on va suivre la syntaxe suivante :
Code : SQL
DECLARE type_gestionnaire HANDLER FOR condition_valeur requete;
Il existe deux types de gestionnaires actuellement supports, qui sont :
EXIT : lors de la rencontre d'une erreur, la procdure s'arrte (comportement par dfaut).
CONTINUE : lors de la rencontre d'une erreur, la procdure continue.
Si on avait mis EXIT la place de CONTINUE dans l'exemple prcdent, la phrase 'je suis 3' ne serait pas apparue.
Vient ensuite condition_valeur qui est subtile dans la mesure o il existe plusieurs conditions possibles, et que parmi elles,
certaines reprennent un code d'erreur standard SQL, les autres provenant du standard de MySQL.
Par exemple : ci-dessus, j'ai mis la valeur 1062 qui correspond au code d'erreur MySQL pour les cls dupliques, mais j'aurais
aussi bien pu utiliser le code d'erreur standard la place, ce qui donne ceci :
Code : SQL
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SELECT 'ERREUR';
Procdure stocke 11/22
www.siteduzero.com
Comme vous pouvez le remarquer, le mot cl SQLSTATE est venu en plus du code, et le numro de l'erreur est entour ; si vous
ne le faites pas, vous aurez une erreur. De mme, si vous utilisez uniquement le code d'erreur sans dclarer SQLSTATE, vous
aurez aussi une erreur (l'erreur du manuel MySQL est l).
Il existe encore d'autres conditions :
SQLWARNING : raccourci pour tous les codes SQLSTATE qui commencent par 01.
NOT FOUND : raccourci pour tous les codes SQLSTATE qui commencent par 02.
SQLEXCEPTION : raccourci pour tous les codes SQLSTATE qui ne sont pas reprsents par SQLWARNING ou par NOT
FOUND.
Et si on veut plusieurs codes d'erreurs ?
C'est tout fait possible, par exemple :
Code : SQL
CREATE PROCEDURE erreur_continue ()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000', SQLEXCEPTION SELECT
'ERREUR';
SELECT 'je suis 1';
INSERT INTO t VALUES (1);
SELECT 'je suis 2';
INSERT INTO t VALUES (1);
SELECT 'je suis 3';
END;
|
Vous avez donc vu tout ce qu'il est possible de faire avec les gestionnaires ; remarquez que la requte que j'ai mise en fin est un
exemple, vous pouvez tout fait effectuer un autre traitement, voire mme mettre des blocs d'instructions.
Exemple :
Code : SQL
CREATE PROCEDURE erreur_continue ()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
SELECT 'ERREUR';
SELECT 'je suis une instruction du bloc d\'erreur';
END;
SELECT 'je suis 1';
INSERT INTO t VALUES (1);
SELECT 'je suis 2';
INSERT INTO t VALUES (1);
SELECT 'je suis 3';
END;
|
Est-il possible d'avoir une gestion nominative des erreurs ?
Oui, ce qui permet d'ailleurs une meilleur lisibilit.
Reprenons notre code prcdent et rajoutons-y ce qui manque :
Code : SQL
CREATE PROCEDURE condition_propre ()
BEGIN
Procdure stocke 12/22
www.siteduzero.com
DECLARE condition_cle_duplique CONDITION FOR SQLSTATE '23000';
DECLARE CONTINUE HANDLER FOR condition_cle_duplique SELECT 'ERREUR';
SELECT 'je suis 1';
INSERT INTO t VALUES (1);
SELECT 'je suis 2';
INSERT INTO t VALUES (1);
SELECT 'je suis 3';
END;
|
La nouvelle ligne est la suivante :
Code : SQL
DECLARE condition_cle_duplique CONDITION FOR SQLSTATE '23000';
Dtaillons-la donc selon sa syntaxe.
Code : SQL
DECLARE nom_type_erreur CONDITION FOR type_erreur;
Nous dfinissons donc ici un nom qui sera utilisable quand la condition suivante est rencontre. Dans notre cas, nous avons dit
d'associer 'condition_cle_duplique' l'erreur de cl duplique (code d'erreur 23000 en SQL Standard). Il est donc possible par la
suite de donner ce nom plutt qu'un nom peu parlant.
Le nom ainsi cr devra tre appel la place du type d'erreur attendu dans :
Code : SQL
DECLARE CONTINUE HANDLER FOR condition_cle_duplique SELECT 'ERREUR';
Tout ceci vous permettra une meilleure conception de vos procdures, et surtout la possibilit de leur apporter une certaine
autonomie face aux erreurs.
Vous pouvez trouvez la liste des erreurs sur la documentation officielle.
Curseur
Jusqu' maintenant, ce que vous avez vu vous permet de construire des procdures relativement intressantes : cependant, vous
serez vite confronts au problme de la lecture des rsultats lorsqu'une requte SELECT renvoie plus d'une ligne.
Pour remdier cela, il y a les curseurs qui pour le moment sont peu volus (car ils sont en lecture seule et non navigable) dans
MySQL ; mais ils nous suffiront.
Imaginons que nous ayons une table de membres : nous souhaiterions lire l'identifiant et le mot de passe qui y sont contenus, ce
qui donne la chose suivante :
Code : SQL
CREATE PROCEDURE liste_membres()
BEGIN
DECLARE var_identifiant VARCHAR(64);
DECLARE var_mot_passe VARCHAR(32);
DECLARE curseur1 CURSOR FOR SELECT identifiant, mot_passe
FROM membres;

OPEN curseur1; # ouverture du curseur1

# premire ligne du rsultat
Procdure stocke 13/22
www.siteduzero.com

FETCH curseur1 INTO var_identifiant, var_mot_passe;
SELECT var_identifiant, var_mot_passe;

# seconde ligne du rsultat
FETCH curseur1 INTO var_identifiant, var_mot_passe;
SELECT var_identifiant, var_mot_passe;

# troisime ligne du rsultat
FETCH curseur1 INTO var_identifiant, var_mot_passe;
SELECT var_identifiant, var_mot_passe;

CLOSE curseur1; # fermeture du curseur1
END;
Premire chose remarquer, cette structure ne rcupre que trois des lignes, ce qui n'est pour le moment que peu intressant
pour nous ; dans les parties suivantes, nous verrons comment simplifier a tout en permettant une lecture totale du jeu de
rsultats.
Premire chose effectue dans cet exemple aprs avoir dclar deux variables locales qui nous resserviront plus bas :
Code : SQL
DECLARE curseur1 CURSOR FOR SELECT identifiant, mot_passe FROM
membres;
On demande la cration d'un curseur nomm 'curseur1' qui va aller chercher le jeu de rsultats correspondant la requte :
SELECT identifiant, mot_passe FROM membres;
Ensuite, afin de pouvoir utiliser notre jeu de rsultats et parcourir ce qui est l'intrieur, nous l'ouvrons avec ceci :
Code : SQL
OPEN curseur1;
S'ensuit la partie :
Code : SQL
FETCH curseur1 INTO var_identifiant, var_mot_passe;
Nous lisons le rsultat du curseur1 pour la ligne courante. Chaque appel FETCH fait avancer d'une ligne dans le jeu de
rsultats.
Nous affectons le rsultat de cette ligne nos variables.
Remarquez bien que les variables doivent tre disposes dans le sens dans lequel on souhaite rcuprer les valeurs ; si
dans le cas prsent, nous avions invers
Code : SQL
FETCH curseur1 INTO var_identifiant, var_mot_passe;
avec
Code : SQL
FETCH curseur1 INTO var_mot_passe, var_identifiant;
nous aurions alors eu les mots de passe stocks dans la variable qui taient pour les identifiants, et inversement.
Procdure stocke 14/22
www.siteduzero.com
Enfin, aprs avoir rcupr nos lignes, nous fermons le curseur1 l'aide de :
Code : SQL
CLOSE curseur1;
Instructions de contrle
IF
Vous souhaiteriez certainement dans certains cas vrifier des valeurs et effectuer des actions en consquence : le IF est l pour
vous permettre ce genre de choses.
Imaginons la procdure suivante :
Code : SQL
CREATE PROCEDURE controle_if(IN var INT)
BEGIN
IF var = 1 THEN
SELECT 'Il est vrai de dire que 1 = 1 :D';
ELSE
SELECT 'Fou est celui qui vous dira que 1 est gal
autre chose que 1 :D';
END IF;
END|
CALL controle_if(1)|
CALL controle_if(2)|
Procdure simple qui compare la variable passe en paramtre la procdure avec 1. Si les deux sont gaux, alors le rsultat
suivant est excut, et si ce n'est pas le cas, la partie contenue aprs le ELSE (sinon) est quant elle excute.
L'appel des deux CALL nous dmontre bien le rsultat.
Y a pas moyen de mettre plusieurs IF ?
Il est tout fait possible de mettre plusieurs conditions, ce qui donne la chose suivante :
Code : SQL
CREATE PROCEDURE controle_if(IN var INT)
BEGIN
IF var = 1 THEN
SELECT 'Il est vrai de dire que 1 = 1 :D';
ELSEIF var = 2 THEN
SELECT 'Il est vrai de dire que 2 = 2 :D';
ELSE
SELECT 'La variable passe en paramtre vaut autre
chose que 1 et 2';
END IF;
END|
CALL controle_if(1)|
CALL controle_if(2)|
CALL controle_if(3)|
Pour chaque condition que vous souhaiterez ajouter, il vous suffira d'ajouter une ligne :
Code : SQL
ELSEIF condition_vrai THEN requetes
Procdure stocke 15/22
www.siteduzero.com
On peut mettre plusieurs requtes ?
Oui, ce qui peut par exemple donner ceci :
Code : SQL
CREATE PROCEDURE controle_if(IN var INT)
BEGIN
IF var = 1 THEN
SELECT 'Il est vrai de dire que 1 = 1 :D';
ELSEIF var = 2 THEN
SELECT 'Il est vrai de dire que 2 = 2 :D';
SELECT 'Je suis 2';
ELSE
SELECT 'La variable passe en paramtre vaut autre
chose que 1 et 2';
SELECT var;
END IF;
END|
CALL controle_if(1)|
CALL controle_if(2)|
CALL controle_if(3)|
CASE
Cette syntaxe, qui diffre du CASE normal, va vous permettre d'effectuer une action si une condition est vrifie.
Il existe deux types de syntaxes : la premire se rapprochant de l'utilisation du 'SWITCH' dans les langages de programmation, et
l'autre tant quivalente une succession de 'IF ... ELSEIF ... ELSEIF ... ELSE ...' .
Exemple Syntaxe1 :
Code : SQL
CREATE PROCEDURE case1(IN var INT)
BEGIN
CASE var
WHEN 1 THEN SELECT 'Je suis 1';
WHEN 2 THEN SELECT 'Je suis 2';
ELSE SELECT 'Je suis autre chose que 1 et 2';
END CASE;
END|
Dans ce cas, la variable 'var' est compare chaque cas rencontr, et si aucune des valeurs n'est vrifie dans les WHEN, alors
l'instruction aprs ELSE sera excute.
Exemple Syntaxe2 :
Code : SQL
CREATE PROCEDURE case2(IN var INT)
BEGIN
CASE
WHEN var = 1 THEN SELECT 'Je suis 1';
WHEN var = 2 THEN SELECT 'Je suis 2';
ELSE SELECT 'Je suis autre chose que 1 et 2';
END CASE;
END|
Procdure stocke 16/22
www.siteduzero.com
Dans ce cas, la variable 'var' n'est pas value ; au lieu de cela, nous passons d'un bloc de WHEN l'autre en comparant si une
expression est vraie. Si c'est le cas, nous excutons alors l'instruction qui la suit, sinon, si aucune des expressions n'est vrifie,
alors l'instruction du ELSE est effectue.
Est-il possible de mettre plus d'une instruction dans THEN ?
Oui vous n'tes pas limits une instruction.
LOOP
C'est une structure de boucle qui rpte un bloc d'instructions tant qu'elle ne rencontre pas une instruction LEAVE pour l'arrter.
Exemple :
Code : SQL
CREATE PROCEDURE loop1()
BEGIN
DECLARE i INT DEFAULT 0;

LOOP
SET i := i + 1;
SELECT i;

END LOOP;
END|
Cette requte est correcte, cependant, ne la testez pas car vous auriez une boucle qui dure trs longtemps (Ctrl + C
sous Windows pour arrter le dsastre).
Aucune condition d'arrt n'a t rencontre, et une erreur ne sera rencontre que lorsque la valeur maximale valide de INT sera
rencontre, soit le chiffre : 2 147 483 647.
Comme pour toutes les instructions de boucle qui seront prsentes, il est possible d'arrter brusquement la boucle
l'aide d'une instruction du type :
Code : SQL
LEAVE nom_label
Exemple d'arrt lorsqu'un label est prsent :
Code : SQL
CREATE PROCEDURE loop1()
BEGIN
DECLARE i INT DEFAULT 0;

je_suis_un_label: LOOP
SET i := i + 1;
SELECT i;

IF i = 10 THEN
LEAVE je_suis_un_label;
END IF;

END LOOP je_suis_un_label;
END|
Procdure stocke 17/22
www.siteduzero.com
Le code s'excute, et si i vaut 10, alors la boucle est arrte grce au nom du label.
Le label indiqu avant l'instruction de boucle doit tre le mme que celui qui la termine.
REPEAT
Cette instruction de type boucle permet de rpter un bloc d'instructions jusqu' ce qu'une condition soit vrifie.
Exemple :
Code : SQL
CREATE PROCEDURE repeat1()
BEGIN
DECLARE i INT DEFAULT 0;

REPEAT
SET i := i + 1;
SELECT i;

UNTIL i = 10 END REPEAT;
END|
Une boucle est lance jusqu' ce que la valeur de variable locale i soit gale 10.
Plus court que la version avec LOOP pour un rsultat identique.
Les labels sont supports de la mme manire qu'avec LOOP et prennent donc la mme syntaxe.
WHILE
C'est une structure de type boucle qui rpte un bloc d'instructions tant qu'une condition est vraie.
Exemple :
Code : SQL
CREATE PROCEDURE while1()
BEGIN
DECLARE i INT DEFAULT 0;

WHILE i < 10 DO
SET i := i + 1;
SELECT i;

END WHILE;
END|
Tant que la variable locale i est infrieure 10, le bloc d'instructions est excut.
Les label sont supports de la mme manire qu'avec LOOP et prennent donc la mme syntaxe.
Procdure stocke 18/22
www.siteduzero.com
ITERATE
ITERATE ne peut tre utilise qu' l'intrieur d'une boucle LOOP, REPEAT ou WHILE et signifie : "excute encore une fois la
boucle".
Et plus clairement ?
Le mieux sera encore des exemples reprenant nos procdures prcdentes.
Exemple LOOP :
Code : SQL
CREATE PROCEDURE loop1()
BEGIN
DECLARE i INT DEFAULT 0;

je_suis_un_label: LOOP
SET i := i + 1;
SELECT i;

IF i < 10 THEN ITERATE je_suis_un_label; END
IF;

SELECT 'Je suis ', i;
LEAVE je_suis_un_label;
END LOOP je_suis_un_label;
END|
Concrtement la boucle se lance, fait ses instructions, arrive sur la condition qui vrifie que la variable locale i est infrieure 10 ;
si c'est le cas, la boucle est relance.
Vous remarquerez en testant la procdure que la phrase n'est affiche que lors de la dernire boucle : ce qui veut dire que lors des
premires boucles, ds qu'on lui dit ITERATE, elle relance tout de suite la boucle portant le label demand, sans passer par le
code qui est en dessous. Ce comportement est quelque peu droutant et source d'erreur ; donc, quand vous utilisez ceci, faites
bien attention et testez davantage.
Exemple REPEAT :
Code : SQL
CREATE PROCEDURE repeat1()
BEGIN
DECLARE i INT DEFAULT 0;

je_suis_un_label: REPEAT
SET i := i + 1;
SELECT i;

IF i < 10 THEN ITERATE je_suis_un_label; END
IF;

SELECT 'Je suis ', i;
UNTIL i < 20 END REPEAT je_suis_un_label;
END|
Si nous excutions la mme chose sans le IF contenant le ITERATE, la boucle s'arrterait au premier tour ; pourtant, en mettant
cette ligne, on s'aperoit que la valeur est bien incrmente jusqu' 10, on retrouve notre rsultat du LOOP, ce comportement est
droutant : la vigilance est donc de mise lorsque vous utilisez le ITERATE avec le REPEAT.
Exemple WHILE :
Code : SQL
Procdure stocke 19/22
www.siteduzero.com
CREATE PROCEDURE while1()
BEGIN
DECLARE i INT DEFAULT 0;

je_suis_un_label: WHILE i < 10 DO
SET i := i + 1;
SELECT i;

IF i < 10 THEN ITERATE je_suis_un_label; END
IF;

SELECT 'Je suis ', i;
END WHILE je_suis_un_label;
END|
Tant que i est infrieur 10, on excute le bloc ; remarquez que le message est affich seulement dans la dernire boucle.
Exemples
Vous trouverez dans cette partie des exemples de procdures prtes l'emploi, ou qui permettent de rpondre des problmes
spcifiques.
Puissance d'un nombre : X exposant n
Code : SQL
DELIMITER |
#Exemple de procdure calculant X exposant n
CREATE PROCEDURE Math_Puissance(IN X INT UNSIGNED, IN exposant
TINYINT, OUT resultat BIGINT UNSIGNED)
BEGIN
DECLARE o BIGINT UNSIGNED DEFAULT 1;

WHILE exposant > 0 DO
SET o := o * X;
SET exposant := exposant - 1;
END WHILE ;
SELECT o INTO resultat;
END|
DELIMITER ;
La procdure est appele ainsi :
Code : SQL
CALL Math_Puissance(3,3,@a); #appel de la procdure
SELECT @a; #affichage du rsultat
Lister les Membres d'une table :
Code : SQL
DELIMITER |
#Exemple de procdure qui liste les membres d'une table
CREATE PROCEDURE Liste_Membres()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE var_identifiant VARCHAR(64);
DECLARE var_mot_passe VARCHAR(32);
DECLARE curseur1 CURSOR FOR SELECT identifiant, mot_passe FROM
membres;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
Procdure stocke 20/22
www.siteduzero.com
'

OPEN curseur1; # ouverture du curseur1

REPEAT
FETCH curseur1 INTO var_identifiant, var_mot_passe;
IF done = 0 THEN
SELECT var_identifiant, var_mot_passe;
END IF;
UNTIL done
END REPEAT;

CLOSE curseur1; # fermeture du curseur1
END|
DELIMITER ;
La procdure est appele par :
Code : SQL
CALL Liste_Membres();
Au final, les procdures stockes reprsentent un bon moyen d'optimiser les requtes redondantes, tout en offrant une structure
suffisamment large pour permettre des applications volues.
Partager

Procdure stocke 21/22
www.siteduzero.com

Das könnte Ihnen auch gefallen