Tout comme Oracle possède son langage PL/SQL et MS SQL Server son Transact-SQL, MySQL possède aussi un langage de programmation.
la programmation sous MySQL regroupe
- les triggers
- les procédures stockées
- les fonctions
Les Procédures Stockées
Une procédure stockée est un petit programme stocké dans la base de données et appelable à partir d'un client comme on peut le faire pour une requête. Une procédure est executée par le serveur de base de données.
Tous les exemples de ce tuto ont été tapés en utilisant le client mySQL dans une console. Vous pouvez si vous le souhaitez, utiliser MySQL Workbench ou PhpMyadmin (sauf pour les triggers).
Lorsque l'on crée une procédure, un des premiers soucis à contourner et tout bête : comment puis-je écrire une instruction qui se termine par un point-virgule alors que ma procédure contient un point-virgule à chaque ligne ?
La réponse est : changeons le caractère délimiteur par un autre qui ne risque pas d'apparaitre dans nos intructions, prenons par exemple le pipe '|'
Créons notre procédure avec la commande CREATE PROCEDURE name ([param[,param ...]])
On peut utiliser des paramètres IN, OUT ou INOUT c'est à dire en Entrée, en Sortie et à la fois en Entrée et en Sortie.
Chaque paramètre est défini par son sens, son nom et son type.
Voici un premier exemple d'une procedure qui met à jour les prix en leur appliquant un coefficient
Notez le | final qui nous fait sortir de l'édition
Chaque bloc d'instructions doit être encadré par BEGIN et END comme en Pascal, mais peut être ignoré dans le cas d'une seule instruction.
Pour lancer notre procédure, on pense à remettre le délimiteur standard, c'est à dire le point-virgule.
On lance une procédure par une commande call en SQL
en php avec PDO cela donnerait :
Utilisation d'un paramètre de retour
Pour affecter un résultat SQL à une variable, on utilise le mot clé INTO
Pour récupérer le résultat, on doit initialiser la variable qui va recevoir le résultat
Pour modifier une procédure, il faut la supprimer avec DROP puis la recréer, il n'existe pas de commande ALTER PROCEDURE
Pour afficher le code d'une procédure
Pour voir les procédures existantes
Déclaration des variables
Les variables sont déclarées par le mot clé DECLARE et les types sont les types SQL de MySQL
On peut déclarer plusieurs variables du même type sur la même ligne
On peut fixer une valeur d'initialisation.
Les commentaires
Affectation directe de variables
On utilise le mot clé SET
Retouner des enregistrements
Si une procédure execute une requête SELECT, les enregistrements résultant sont retournés.
Du coup on peut l'appeler comme une requête SELECT mis à part le 'call'
Cela donne en php :
Notez qu'il n'est pas possible d'appeler la procédure à partir d'une autre Requête
SELECT * FROM mesenreg(); // Ne fonctionne pas, il faut plutot faire une Vue
Les Fonctions
Une fonction comme une procédure s'exécute sur le serveur, mais une fonction retourne un résultat et peut être utilisée directement dans une requête SQL .
Création de fonction
On utilise la commande CREATE FUNCTION name (params) RETURNS returnType
en cas d'erreur 1418
Utilisation d'une fonction stockée dans une requête SQL
Pour la création de routines telles que procedures ou fonctions, il faut posséder le droit ALTER ROUTINE
Exemple de fonction qui arrondit un montant à 50 centimes prés
Conditions IF THEN ELSE
Conditions CASE
Suivant la valeur de la variable qui suit CASE, le programme va traiter tel ou tel cas
Boucles LOOP
Si on souhaite sortir de la boucle on doit rajouter une étiquette. L'appel à LEAVE suivi de l'étiquette provoque la sortie de la boucle.
Boucles REPEAT UNTIL
Si on veut recommencer l'itération
Boucles WHILE
Utilisation des curseurs (CURSOR)
Un CURSOR, c'est ce qui va nous permettre de parcourir un jeu d'enregistrements.
On doit commencer par déclarer le curseur et l'associer à une requête de type SELECT, celle qui va fournir les enregistrements.
Pour cela on doit le déclarer et lui donner un nom :
Avant de l'exécuter, il faut déclarer des variables qui récupéreront les valeurs des champs
On doit ensuite ouvrir le curseur avec OPEN pour exécuter la requête.
A chaque boucle on 'FETCH' les valeurs dans les variables :
ensuite il faut fermer le curseur pour libérer les ressources
Les Triggers
Les Triggers ou déclencheurs en français, sont des procédures attachées directementà un évênement d'une table, par exemple sur chaque insertion ou chaque suppression d'enregistrement.
Un Trigger est donc rattaché à une table et à un évênement, mais on doit aussi indiquer si notre code sera déclenché avant ou après l'évênement.
L' action_time précise si l'action a lieu avant (BEFORE) ou après (AFTER) l'évênement.
L' event c'est l'action sur laquelle on se rattache : INSERT, DELETE, UPDATE
Prenons un exemple cher à Grafikart, celui des messages et topics de forum :
Nous voulons qu'à chaque nouveau message, le champ message_at du topic soit mis à jour à la date courante.
Dans le trigger, on accède aux données de l'enregistrement à insérer avec le préfixe NEW
Le FOR EACH ROW est obligatoire même si dans notre cas nous ne traitons qu'un seul enregistrement.
Supposons que nous voulions supprimer un message, la date du topic doit être mise à jour avec :
- Soit la date de l'avant-dernier message s'il existe
- Soit null s'il n'existe pas
Autre solution en plaçant le trigger après la suppression.
Dans ce cas le message est déja supprimé, on recherche donc la date du dernier message s'il existe.
Utilisation de trigger pour gérer un compteur de messages
On suppose que la table topic contient le nombre de messages
Pour cela on rajoute un champ nb_messages initialisé à zéro.
On crée un trigger sur l'ajout de message et un autre sur la suppression
On crée un trigger sur la suppression de message
Comportement avec les Auto-increment
Supposons que lorsque l'on crée un topic, on crée automatiquement un premier message qui reprend la description du topic
Que nous donne le lastInsertId, celui du message ou celui du topic ?
Réponse : celui du topic
Suppression en cascade
Lorsque l'on crée une liaison entre deux tables, on a la possiblité de définir une suppession en cascade
Cela signifie que si on supprime un topic, tous ses messages sont supprimés dans la foulée (sans avoir besoin de trigger).
Le problème c'est que la suppression dans la table mère désactive le trigger DELETE de la table fille !!!
Il faut choisir l'un ou l'autre.
Quelques commandes utiles
Voir les triggers en place
Avec MySQL Workbench
On a la possibilité d'éditer un trigger existant.
Dans l'explorateur d'objets, faire un clic doit sur le nom de la table puis 'alter table', ensuite sélectionner l'onglet Trigger.
Le trigger sera automatiquement Droppé s'il existe puis recréé.
Voilà pour ce tutoriel qui je l'espère vous donnera des idées pour vos prochains développements.