Formation PUB010 : PHP, 2025 Déboguer une requête SQL

26.1 Comment bien tester la structure de code pour les requêtes


À chaque fois que vous écrivez du code, il importe de tester tous les chemins possibles pour assurer que le programme réagira bien à toutes les situations.

Dans le cas où votre code effectue une requête SELECT pour récupérer des informations dans une base de données, vous devez tester les scénarios suivants :

  • la requête a retourné plusieurs enregistrements;
  • la requête a retourné un  seul enregistrement;
  • elle n'a retourné aucun enregistrement;
  • elle a planté.

Lors de l'ajout, de la modification et de la suppression d'enregistrements, il faut également tenir compte des problèmes liés aux contraintes d'intégrité référentielle, aux chaînes trop longues, aux types de données, etc.

Tester le code qui réagit à une requête ne retournant aucun enregistrement

Une façon simple de tester ce code consiste à ajouter un WHERE pour lequel il n'y a aucune correspondance.

Ex : la requête suivante, lorsqu'elle sera exécutée, conduira à l'affichage du message non technique indiquant qu'aucun enregistrement n'a été trouvé.

PHP

$requete = "SELECT id, prenom, nomfamille FROM clients WHERE id=-1 ORDER BY nomfamille, prenom";

Tester le code qui réagit à une requête qui plante

Pour générer une requête qui plante, vous pouvez simplement changer le nom d'un champ dans la requête.

Ex : l'exécution de la requête suivante conduira à l'affichage du message indiquant qu'un problème est survenu. Si vous le désirez, vous pouvez faire afficher un second message qui, lui, sera technique. N'oubliez pas qu'un message technique doit être généré à l'aide d'une fonction qui assure que le message ne sera généré que si on est en mode débogage.

PHP

$requete = "SELECT id2, prenom, nomfamille FROM clients ORDER BY nomfamille, prenom";

Tester une requête INSERT ou UPDATE lorsqu'une contrainte d'intégrité référentielle est en jeu

Il faut s'assurer que le programme réagira bien si on tente d'insérer ou de modifier une clé étrangère dont la valeur n'existe pas dans la table parent. Pour y arriver, on utilisera temporairement une valeur codée en dur dans notre requête.

Dans l'exemple suivant, le client 999 n'existe pas. En forçant l'utilisation de cette valeur, on verra si le programme réagit correctement.

Remarquez l'utilisation d'une requête préparée, qui sera étudiée plus tard.

PHP

$requete = "INSERT INTO voitures(modele, annee, client_id) VALUES(?, ?, ?);";

...

$stmt->bind_param("ssi", $_POST['modele'], $_POST['annee'], 999);

Utiliser la vraie requête ou la requête qui fait planter le test ?

Après avoir testé si le programme réagit bien aux différents problèmes qui pourraient survenir, il faut prendre soin de remettre la requête dans son état original. 

Pour éviter tout oubli, il est possible d'utiliser une constante de débogage de requête qui indiquera si on doit utiliser la vraie requête ou celle qui fait exprès pour faire échouer le test. Cette constante, que nous appellerons DEBUG_SQL sera initialisée au même endroit que la constante qui indique si on est en mode développement (DEVEL).

PHP

if (defined('DEBUG_SQL') && DEBUG_SQL === true) {

   $requete = "SELECT id, prenom, nomfamille FROM clients WHERE id=-1 ORDER BY nomfamille, prenom";

}

else {

    $requete = "SELECT id, prenom, nomfamille FROM clients ORDER BY nomfamille, prenom";

}

Remarquez que ceci n'a pas besoin d'être fait systématiquement partout dans le programme. Une fois que vous êtes assurés que votre structure de code couvre bien tous les cas d'erreurs possibles, vous pouvez le répliquer ailleurs sans refaire tous les tests.

Tester une requête DELETE lorsqu'une contrainte d'intégrité référentielle est en jeu

Dans le cas où une contrainte d'intégrité empêche la suppression d'un enregistrement, le programme pourra, selon les besoins, annuler la suppression et afficher un message clair ou demander une confirmation avant de supprimer le ou les enregistrements de la table enfant puis l'enregistrement de la table parent.

Contrairement aux autres cas présentés plus haut, il n'est pas possible d'effectuer les tests appropriés seulement en modifiant le code. Pour s'assurer que le programme réagit correctement, il faut modifier les données afin qu'il y ait effectivement au moins un enregistrement dans la table enfant qui est lié à l'enregistrement que l'on s'apprête à supprimer (ex : on ajoutera une voiture associée au client 3 puis on tentera de supprimer le client 3).

▼Publicité

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Merci de partager !
Soumettre