Message d'erreur liée à une contrainte de clé étrangère
Résolu
emrh
Messages postés
427
Date d'inscription
Statut
Membre
Dernière intervention
-
emrh Messages postés 427 Date d'inscription Statut Membre Dernière intervention -
emrh Messages postés 427 Date d'inscription Statut Membre Dernière intervention -
A voir également:
- Message d'erreur liée à une contrainte de clé étrangère
- Clé usb non détectée - Guide
- Clé windows 8 - Guide
- Recuperer message whatsapp supprimé - Guide
- Formater clé usb - Guide
- Message supprimé whatsapp - Guide
9 réponses
yg_be
Messages postés
23541
Date d'inscription
Statut
Contributeur
Dernière intervention
Ambassadeur
1 584
bonjour,
peux-tu nous montrer le contenu complet de contrat-ajout2.php?
peux-tu nous montrer le contenu complet de contrat-ajout2.php?
<?php ob_start(); header("Cache-Control:no-cache"); // --------------------------------------------- // 1 - Vérification droit accès à cette page : | // --------------------------------------------- // Est-ce que la session existe ? session_start(); if (!isset($_SESSION['login2'])) { header('Location: index.php'); exit(); } // --------------------------------------------------------- // 2 - Vérification de la durée de la session actuelle : | // --------------------------------------------------------- // Est-ce que la session est encore valide ? if (time() - $_SESSION['derniereaction2'] > 900) { // la session a expiré, retour page d'accueil session_unset(); session_destroy(); header('Location: index.php'); exit(); } // LA SESSION EST TOUJOURS EN COURS, ON CONTINUE $_SESSION['derniereaction2'] = time(); // on relance la durée de la session if ($_SESSION['action'] <> "contrat-ajout") { $message = "Comment êtes-vous arrivé ici !"; $message2 = "à l'accueil..."; header('Refresh: 3; URL= accueil.php'); $alerte = "1"; } else { // Des prestations sont elles sur le contrat ? if (!isset($_POST["chaine_contrat"]) || $_POST["chaine_contrat"] == "") { $alerte = "1"; $message = "Il n'y a pas de prestation sur ce contrat !"; $message2 = "à la page précédente..."; //récupération PROPRE des variables AVANT de les utiliser $client = !empty($_POST['client']) ? $_POST['client'] : NULL; $batiment = !empty($_POST['batiment']) ? $_POST['batiment'] : NULL; $date_debut = !empty($_POST['date_debut']) ? $_POST['date_debut'] : NULL; $heure_debut = !empty($_POST['heure_debut']) ? $_POST['heure_debut'] : NULL; $date_fin = !empty($_POST['date_fin']) ? $_POST['date_fin'] : NULL; $heure_fin = !empty($_POST['heure_fin']) ? $_POST['heure_fin'] : NULL; $adultes = !empty($_POST['adultes']) ? $_POST['adultes'] : NULL; $enfants = !empty($_POST['enfants']) ? $_POST['enfants'] : NULL; $bebes = !empty($_POST['bebes']) ? $_POST['bebes'] : NULL; $animaux = !empty($_POST['animaux']) ? $_POST['animaux'] : NULL; //récupération des saisies formulaire : $_SESSION['client'] = htmlspecialchars($client); $_SESSION['batiment'] = htmlspecialchars($batiment); $_SESSION['date_debut'] = htmlspecialchars($date_debut); $_SESSION['heure_debut'] = htmlspecialchars($heure_debut); $_SESSION['date_fin'] = htmlspecialchars($date_fin); $_SESSION['heure_fin'] = htmlspecialchars($heure_fin); $_SESSION['adultes'] = htmlspecialchars($adultes); $_SESSION['enfants'] = htmlspecialchars($enfants); $_SESSION['bebes'] = htmlspecialchars($bebes); $_SESSION['animaux'] = htmlspecialchars($animaux); header('Refresh: 3; URL= contrat-ajout1.php'); } else { // TOUT EST BON, ON VA ENREGISTRER LE CONTRAT DANS LA BASE DE DONNÉES : // Connexion à la base de données : require ("connexion.php"); // Récupération de la date du jour : $date_contrat = date('Y/m/d'); // La facture n'existe pas encore : $facture='0'; // Récupération des données formulaire : $client = $_POST['client']; $batiment = $_POST['batiment']; $date_debut = $_POST['date_debut']; $heure_debut = $_POST['heure_debut']; $date_fin = $_POST['date_fin']; $heure_fin = $_POST['heure_fin']; $adultes = $_POST['adultes']; $enfants = $_POST['enfants']; $bebes = $_POST['bebes']; $animaux = $_POST['animaux']; $chaine_contrat = $_POST['chaine_contrat']; $tab_contrat = explode('|', $chaine_contrat); //Requête préparée pour l'ajout : $requete = $bdd->prepare('INSERT INTO contrats(facture, date_contrat, id_client, id_batiment, date_debut, heure_debut, date_fin, heure_fin, adultes, enfants, bebes, animaux) VALUES(:facture, :date_contrat, :id_client, :id_batiment, :date_debut, :heure_debut, :date_fin, :heure_fin, :adultes, :enfants, :bebes, :animaux)'); try { // Exécution de la requête : $requete->execute(array( 'facture' =>$facture, 'date_contrat' => $date_contrat, 'id_client' => $client, 'id_batiment' => $batiment, 'date_debut' => $date_debut, 'heure_debut' => $heure_debut, 'date_fin' => $date_fin, 'heure_fin' => $heure_fin, 'adultes' => $adultes, 'enfants' => $enfants, 'bebes' => $bebes, 'animaux' => $animaux )); } // Problème dans l'enregistrement partie haute du contrat ! catch(Exception $e) { echo "Problème à l'enregistrement de l'entête du contrat !"; header('Refresh: 3; URL= contrat-ajout1.php'); exit(); } // Récupération du dernier ID inséré dans la table contrats : $last_insert_id = $bdd->lastInsertId(); for ($ligne = 0;$ligne < sizeof($tab_contrat);$ligne++) { if ($tab_contrat[$ligne] != "") { $ligne_cont = explode(";", $tab_contrat[$ligne]); //Requête préparée pour l'ajout des éléments qui composent le contrat : $requete2 = $bdd->prepare('INSERT INTO compositions(id_contrat, id_prestation, prix, quantites) VALUES(:id_contrat, :id_prestation, :prix, :quantites)'); $requete2->execute(array( 'id_contrat' => $last_insert_id, 'id_prestation' => $ligne_cont[0], 'prix' => $ligne_cont[2], 'quantites' => $ligne_cont[3] )); } } // L'enregistrement du contrat s'est bien passée, on détruit les variables de session : unset($_SESSION['client']); unset($_SESSION['batiment']); unset($_SESSION['date_debut']); unset($_SESSION['heure_debut']); unset($_SESSION['date_fin']); unset($_SESSION['heure_fin']); unset($_SESSION['adultes']); unset($_SESSION['enfants']); unset($_SESSION['bebes']); unset($_SESSION['animaux']); unset($_SESSION['action']); // On supprimer les variables de formulaire $client = ''; $batiment = ''; $date_debut = ''; $heure_debut = ''; $date_fin = ''; $heure_fin = ''; $adultes = ''; $enfants = ''; $bebes = ''; $animaux = ''; $alerte = "2"; $message = "Le contrat a bien été enregistré !"; $message2 = "à l'accueil..."; // Clôture des requettes : $requete->closeCursor(); $requete2->closeCursor(); header('Refresh: 3; URL= accueil.php'); } }
Le problème est certainement sur ma bdd locale car je viens de transférer mes pages PHP cette fois ci de mon PC local (orid portable) vers mon serveur distant IONOS et je peux ajouter sans problème un contrat qui apparaît bien dans la bdd d'IONOS sans message d'erreur et qui peut quand on l'efface supprimer en CASCADE toutes les 'compositions' liées par l'id_contrat
C'est à dire que je n'ai pas le choix, certaines données sont liées à d'autres tables et jusqu'à maintenant cela fonctionnait et cela fonctionne encore chez Ionos...
Je pense que mes problèmes viennent du moment où j'ai ajouté une colonne en local mais je ne vois pas comment cela pourrait affecter le fonctionnement de des autres colonnes ? J'ai depuis viré cette colonne, mais cela n'a rien changé...
Je peux aussi me passer d'effacer en cascade les données des tables dont certaines infos sont liées par ces clés et procéder plutôt par une deuxième requête, cela me permettrait de supprimer la notion de ON DELETE CASCADE
Je pense que mes problèmes viennent du moment où j'ai ajouté une colonne en local mais je ne vois pas comment cela pourrait affecter le fonctionnement de des autres colonnes ? J'ai depuis viré cette colonne, mais cela n'a rien changé...
Je peux aussi me passer d'effacer en cascade les données des tables dont certaines infos sont liées par ces clés et procéder plutôt par une deuxième requête, cela me permettrait de supprimer la notion de ON DELETE CASCADE
Bonjour,
Hier j'en avais marre de chercher dans tous les sens, et après avoir rapatrié une dernière fois ma
page php du serveur distant Ionos vers mon site local sur mon pc portable, j'ai tout éteint après un
dernier essai raté.
Ce matin, avt d'envoyer un morceau de code supplémentaire pour répondre à la demande d'yg_be
je fais un nouvel essai et tout fonctionne de nouveau en local !!!!!!!
La question que je me pose est : Est-ce que le redémarrage de mon portable y est pour quelque chose ?
si oui quelle manip aurais-je pu faire sur mes tables pour simuler un redémarrage PC car si ce genre
de problème m'arrivait en distant chez IONOS je ne pourrais pas éteindre le serveur pour une nuit !
EDIT : Pour info, le dernier réglage sur le champs id_batiment de ma base de données était :
ON DELETE : RESTRICT
ON UPDATE : RESTRICT
Hier j'en avais marre de chercher dans tous les sens, et après avoir rapatrié une dernière fois ma
page php du serveur distant Ionos vers mon site local sur mon pc portable, j'ai tout éteint après un
dernier essai raté.
Ce matin, avt d'envoyer un morceau de code supplémentaire pour répondre à la demande d'yg_be
je fais un nouvel essai et tout fonctionne de nouveau en local !!!!!!!
La question que je me pose est : Est-ce que le redémarrage de mon portable y est pour quelque chose ?
si oui quelle manip aurais-je pu faire sur mes tables pour simuler un redémarrage PC car si ce genre
de problème m'arrivait en distant chez IONOS je ne pourrais pas éteindre le serveur pour une nuit !
EDIT : Pour info, le dernier réglage sur le champs id_batiment de ma base de données était :
ON DELETE : RESTRICT
ON UPDATE : RESTRICT
(Je n'arrive plus à continuer ce fil de discussion ni sur Chrome ni sur Firefox...donc je le commente ????)
EDIT 2 : J'ai remis ON DELETE : CASCADE sur le champs 'id_contrat' de la table 'compositions' le message est réapparu. Pour testé, j'ai supprimé la contrainte de la table 'compositions' pour la mettre sur la table principale 'contrats' : le message d'erreur n’apparaît pas mais quand je supprime un contrat, évidemment tous les éléments qui le composent dans la table 'compositions' ne disparaissent pas !
EDIT 2 : J'ai remis ON DELETE : CASCADE sur le champs 'id_contrat' de la table 'compositions' le message est réapparu. Pour testé, j'ai supprimé la contrainte de la table 'compositions' pour la mettre sur la table principale 'contrats' : le message d'erreur n’apparaît pas mais quand je supprime un contrat, évidemment tous les éléments qui le composent dans la table 'compositions' ne disparaissent pas !
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
yg_be
Messages postés
23541
Date d'inscription
Statut
Contributeur
Dernière intervention
Ambassadeur
1 584
Ton soucis est donc avec l'insertion dans la table compositions.
Ce serait bien d'également mettre cela dans un try/catch, et en cas d'erreur, d'afficher la valeur de l'array de paramètres, inclus $last_insert_id.
Ce serait bien d'également mettre cela dans un try/catch, et en cas d'erreur, d'afficher la valeur de l'array de paramètres, inclus $last_insert_id.
Non, mon problème arrive au try/catch de INSERT INTO contrats...
Comme j'ai mis un exit() juste après le message "Problème à l'enregistrement de l'entête du contrat !"
rien ne s'enregistre dans 'contrats' (plantage) et rien dans 'compositions' (exit())
D'autre part, je t'ai donné une copie de mon code parce que tu me l'as demandé mais dans la mesure où
ce même code fonctionne parfaitement sur le serveur de mon hébergeur IONOS j'ai plutôt pensé que le
problème venait de ma bdd...
Comme j'ai mis un exit() juste après le message "Problème à l'enregistrement de l'entête du contrat !"
rien ne s'enregistre dans 'contrats' (plantage) et rien dans 'compositions' (exit())
D'autre part, je t'ai donné une copie de mon code parce que tu me l'as demandé mais dans la mesure où
ce même code fonctionne parfaitement sur le serveur de mon hébergeur IONOS j'ai plutôt pensé que le
problème venait de ma bdd...
tes soucis avec les contraintes, c'était donc simplement parce que tu essayais d'insérer dans compositions alors que l'insertion n'avait pas fonctionné dans contrats.
en cas d'erreur dans le try/catch, il est utile d'afficher de quelle erreur il s'agit.
https://www.php.net/manual/fr/exception.getmessage.php
en cas d'erreur dans le try/catch, il est utile d'afficher de quelle erreur il s'agit.
https://www.php.net/manual/fr/exception.getmessage.php
Excuse moi je ne comprends pas !
1. Si mon plantage se produit au moment de l'enregistrement de la partie haute du contrat (l'en-tête) dans la
table 'contrats' , toute la suite c'est à dire la partie de code concernant le contenu du contrat qui devrait
normalement s'enregistrer dans la table 'compositions' n'est même pas lue par le serveur non ?
2. J'ai mis un catch(Exception $e) sur ma première requête (celle qui plante) et j'ai bien un message d'erreur :
cf mon premier post...
pour rappel :
Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`gite`.`compositions`, CONSTRAINT `contrat` FOREIGN KEY (`id_contrat`) REFERENCES `contrats` (`id_contrat`) ON DELETE CASCADE) in /var/www/html/gite/gestion/contrat-ajout2.php:126 Stack trace: #0 /var/www/html/gite/gestion/contrat-ajout2.php(126): PDOStatement->execute() #1 {main} thrown in /var/www/html/gite/gestion/contrat-ajout2.php on line 126
3. Pourquoi le serveur d'IONOS qui ne plante absolument pas ne réagit t-il pas comme mon serveur local sur mon PC puisque c'est la même page PHP qui tente d'enregistrer les données ?
1. Si mon plantage se produit au moment de l'enregistrement de la partie haute du contrat (l'en-tête) dans la
table 'contrats' , toute la suite c'est à dire la partie de code concernant le contenu du contrat qui devrait
normalement s'enregistrer dans la table 'compositions' n'est même pas lue par le serveur non ?
2. J'ai mis un catch(Exception $e) sur ma première requête (celle qui plante) et j'ai bien un message d'erreur :
cf mon premier post...
pour rappel :
Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`gite`.`compositions`, CONSTRAINT `contrat` FOREIGN KEY (`id_contrat`) REFERENCES `contrats` (`id_contrat`) ON DELETE CASCADE) in /var/www/html/gite/gestion/contrat-ajout2.php:126 Stack trace: #0 /var/www/html/gite/gestion/contrat-ajout2.php(126): PDOStatement->execute() #1 {main} thrown in /var/www/html/gite/gestion/contrat-ajout2.php on line 126
3. Pourquoi le serveur d'IONOS qui ne plante absolument pas ne réagit t-il pas comme mon serveur local sur mon PC puisque c'est la même page PHP qui tente d'enregistrer les données ?
le message d'erreur ne correspond pas au code que tu as partagé en #6.
le try/catch empêche le plantage, donc le code continue, sauf si tu mets un exit().
comme le code continue sans avoir inséré le contrat, il arrive à l'insertion de la composition, qui, sans try/catch, se plante, vu la contrainte qui empêche d'insérer une composition sans contrat
Si tu veux comprendre ce qui se passe, il est nécessaire de faire ce qui est expliqué en #11.
Si c'est trop compliqué pour toi, supprime le try/catch, tu auras un plantage avec un message explicatif.
le try/catch empêche le plantage, donc le code continue, sauf si tu mets un exit().
comme le code continue sans avoir inséré le contrat, il arrive à l'insertion de la composition, qui, sans try/catch, se plante, vu la contrainte qui empêche d'insérer une composition sans contrat
Si tu veux comprendre ce qui se passe, il est nécessaire de faire ce qui est expliqué en #11.
Si c'est trop compliqué pour toi, supprime le try/catch, tu auras un plantage avec un message explicatif.
Ah ok, je comprends...
J'ai ajouté exit() quand je me suis rendu compte que j'allais flinguer ma table 'compositions' avec
l'insertion de données sans que la partie haute soit renseignée dans la table 'contrats'...
Je viens de virer le try/catch et j'ai ça qui est plus parlant du coup :
Fatal error: Uncaught PDOException: SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect time value: '' for column `gite`.`contrats`.`heure_debut` at row 1 in /var/www/html/gite/gestion/contrat-ajout2.php:121 Stack trace: #0 /var/www/html/gite/gestion/contrat-ajout2.php(121): PDOStatement->execute() #1 {main} thrown in /var/www/html/gite/gestion/contrat-ajout2.php on line 121
J'ai ajouté exit() quand je me suis rendu compte que j'allais flinguer ma table 'compositions' avec
l'insertion de données sans que la partie haute soit renseignée dans la table 'contrats'...
Je viens de virer le try/catch et j'ai ça qui est plus parlant du coup :
Fatal error: Uncaught PDOException: SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect time value: '' for column `gite`.`contrats`.`heure_debut` at row 1 in /var/www/html/gite/gestion/contrat-ajout2.php:121 Stack trace: #0 /var/www/html/gite/gestion/contrat-ajout2.php(121): PDOStatement->execute() #1 {main} thrown in /var/www/html/gite/gestion/contrat-ajout2.php on line 121
EDIT : Les champs 'Heure d'arrivée' & 'Heure de départ' n'étant pas obligatoires à la validation du
formulaire je me retrouvais à enregistrer du vide ce qui devait causer l'erreur...
J'ai ajouté ça :
... et tout est réglé !
Merci beaucoup yg_be !
formulaire je me retrouvais à enregistrer du vide ce qui devait causer l'erreur...
J'ai ajouté ça :
$heure_debut = $_POST['heure_debut']; $heure_debut=='' ? $heure_debut='00:00':$heure_debut = $_POST['heure_debut']; $heure_fin = $_POST['heure_fin']; $heure_fin=='' ? $heure_fin='00:00':$heure_fin = $_POST['heure_fin'];
... et tout est réglé !
Merci beaucoup yg_be !