Académique Documents
Professionnel Documents
Culture Documents
Requêtes préparées et
procédures stockées
-- Avec un paramètre
PREPARE select_client
FROM 'SELECT * FROM Client WHERE email = ?';
PREPARE select_race
FROM @req;
SET @id = 3;
EXECUTE select_col_animal USING @id;
SET @client = 2;
EXECUTE select_adoption USING @client, @id;
Usage
MySQL est rarement utilisé seul. La plupart du temps, il est utilisé en
conjonction avec un langage de programmation, comme Java, PHP,
Python, etc.
Un langage de programmation permet de gérer un programme, un site
web… et crée des requêtes SQL permettant de gérer la base de
données de l'application.
Or, il existe des API (interfaces de programmation) pour plusieurs
langages, qui permettent de faire des requêtes préparées sans
exécuter vous-mêmes les commandes PREPARE, EXECUTE et
DEALLOCATE
Exemples : l'API C MySQL pour le langage C, MySQL Connector/J
pour le Java, ou MySQL Connector/Net pour le .Net.
Pour d'autres langages, des extensions ont été créées, en général
elles-mêmes basées sur l'API C MySQL, comme PDO pour le PHP
Illustration : voir fichiers dans TP4 pour le C et PHP
code C utilisant l'API MySQL pour préparer et exécuter une requête d'insertion
code PHP utilisant l'extension PDO pour préparer et exécuter requête de sélection
Fotsing Talla Bernard, PhD Bases de Données : Aspects Avancés 75
3.1 Requêtes préparées : usage et utilité
Par exemple, supposons que dans un site Web vous avez un bouton
qui permet de supprimer un membre à partir de son id envoyé au clic
sur le bouton "Supprimer Compte"
On a donc une requête incomplète DELETE FROM Membre WHERE id = et
de l’autre côté l’id du membre e.g. 4 (obtenu d’une zone de saisie)
Le langage de programmation utilisé va mettre les deux ensemble
pour créer la requête DELETE FROM Membre WHERE id = 4;
Et maintenant, un pirate s'amuse à modifier la donnée envoyée par le
bouton "Supprimer compte" (eh oui, c'est faisable, et même plutôt
facile). À la suite du numéro d'id, il ajoute OR 1 = 1
On obtient au final la requête DELETE FROM Membre WHERE id = 4 OR 1 = 1;
Comme la seconde condition sera toujours remplie, c'est l'horreur :
toute votre table Membre est effacée !
Et voilà ! Vous avez été victime d'une injection SQL.
Exemple
CALL afficher_races() | -- si le délimiteur est toujours | !!!
Exemple
DELIMITER | -- Facultatif si votre délimiteur est toujours |
CREATE PROCEDURE afficher_race_selon_espece (IN p_espece_id INT)
-- Définition du paramètre p_espece_id
BEGIN
SELECT id, nom, espece_id, prix FROM Race
WHERE espece_id = p_espece_id; -- Utilisation du paramètre
END |
DELIMITER ; -- On remet le délimiteur par défaut si on veut
Utilisation
CALL afficher_race_selon_espece(1);
SET @espece_id := 2;
CALL afficher_race_selon_espece(@espece_id);
Exemple 2
DELIMITER |
CREATE PROCEDURE compter_races_selon_espece (p_espece_id INT, OUT p_nb_races INT)
BEGIN
SELECT COUNT(*) INTO p_nb_races FROM Race WHERE espece_id = p_espece_id;
END |
Exemple
DROP PROCEDURE afficher_races;