Partage
  • Partager sur Facebook
  • Partager sur Twitter

Cannot add or update a child row: a foreign key co

Sujet résolu
    27 février 2021 à 16:30:56

    Bonjour,

    Je sais que cette question a déjà été posée, mais je ne trouve pas la solution alors je la repose. J'ai changé la structure de mes tables et lorsque je tente de faire un insert j'obtiens le message : Cannot add or update a child row: a foreign key constraint fails.

    Je précise que j'ai cherché des éventuelles données orphelines mais en vain alors j'ai supprimé ma base puis je l'ai recréée et malgré tout, j'en suis toujours là: Cannot add or update a child row: a foreign key constraint fails.

    voici mes requêtes:

    // INSERTION CLIENT
    $sql1 = 'INSERT INTO clients (nom, email, telephone, adresse, ville, cp) VALUES  (?,?,?,?,?,?)';
    if ($stmt = $conn->prepare($sql1)) {
        $stmt->bind_param('ssssss', $nom, $email, $telephone, $adresse, $ville, $cp);
        $stmt->execute();
    }
    
    // INSERTION DEMANDE
    $client_id = $conn->insert_id;
    $sql2 = 'INSERT INTO demandes (date_dde, client_id, ddeConcerne, fonctionnalites, message) VALUES  (?,?,?,?,?)';
    if ($stmt = $conn->prepare($sql2)) {
        $stmt->bind_param('sisss', $dateActuelle, $client_id, $ddeConcerne, $fonctionnalites, $message);
        $stmt->execute();
    }
    
    // INSERTION DETAILS
    $demande_id = $conn->insert_id;
    $document_id = $conn->insert_id;
    $sql3 = 'INSERT INTO details (demande_id, document_id) VALUES  (?,?)';
    if ($stmt = $conn->prepare($sql3)) {
        $stmt->bind_param('ii', $demande_id, $document_id);
        $stmt->execute();
    }
    
    $sql = 'INSERT INTO documents (file_path, unique_id_doc) VALUES  (?,?)';
    if ($stmt = $conn->prepare($sql)) {
       $stmt->bind_param('ss', $targetFilePath, $_SESSION['unique_id_doc']);
       $stmt->execute();

    Le problème se trouve dans la table détails et voici une copie d'écran de ma base:

    Donc j'essaie d'insérer les données clients avec plusieurs documents et tout fonctionne sauf le détail des documents.

    Je vous remercie de votre aide





    -
    Edité par baraton 27 février 2021 à 16:33:18

    • Partager sur Facebook
    • Partager sur Twitter
      27 février 2021 à 17:30:37

      Bonjour,

      Il faut l'erreur entière, car elle te donne quelle contrainte échoue.

      Et quel INSERT lève l'erreur ?

      Dans tous les cas, tu essayes d'insérer dans une colonne avec clé étrangère une valeur qui n'existe pas dans la table de référence...

      Dans ton code $demande_id et $document_id valent la même chose, le problème est là... il faut INSERT le document avant le détail pour avoir son id ...

      Juste par curiosité, un document peut être lié à plusieurs demandes ?

      -
      Edité par Benzouye 27 février 2021 à 17:46:01

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        27 février 2021 à 18:27:36

        Bonjour,

        Non un document ne peut pas être lié à plusieurs demandes, mais plusieurs documents peuvent être liés à une demande. Après avoir corrigé une erreur: ma requête dans la table détails ne devant pas être exécutée si aucun document n'est joint à la demande.

        jE VIENS DE METTRE LES REQUËTES DANS L'ORDRE

        Voici l'erreur:

        Fatal error: Uncaught mysqli_sql_exception: Cannot add or update a child row: a foreign key constraint fails (`wc-v4`.`details`, CONSTRAINT `details_ibfk_2` FOREIGN KEY (`document_id`) REFERENCES `documents` (`document_id`) ON DELETE CASCADE ON UPDATE CASCADE) in D:\xampp-php-7.3\htdocs\www\WC-V4\upload.php:146 Stack trace: #0 D:\xampp-php-7.3\htdocs\www\WC-V4\upload.php(146): mysqli_stmt->execute() #1 {main} thrown in D:\xampp-php-7.3\htdocs\www\WC-V4\upload.php on line 146

        -
        Edité par baraton 27 février 2021 à 18:33:07

        • Partager sur Facebook
        • Partager sur Twitter
          27 février 2021 à 23:39:45

          Alors la table détail ne sert à rien, au contraire elle pollue...

          Tu devrais juste avoir une clé étrangère demande_id dans la table document...

          Et supprimer cette table détails... qui permet de lier le même document à plusieurs demandes...

          Tu insères dans client, tu récupères l'id, puis tu insères dans demande, tu récupères l'id et enfin tu insères dans document ...

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            28 février 2021 à 9:35:54

            Merci beaucoup tout fonctionne bien.
            • Partager sur Facebook
            • Partager sur Twitter
              1 mars 2021 à 16:33:31

              Je crois que j'ai parlé un peu trop vite car tout fonctionne bien seulement quand j'upload 1 seul fichier sinon, j'ai comme erreur: 

              Fatal error: Uncaught mysqli_sql_exception: Cannot add or update a child row: a foreign key constraint fails (`wc-v4`.`documents`, CONSTRAINT `documents_ibfk_1` FOREIGN KEY (`demande_id`) REFERENCES `demandes` (`demande_id`) ON DELETE CASCADE ON UPDATE CASCADE) in D:\xampp-php-7.3\htdocs\www\WC-V4\upload.php:66 Stack trace: #0 D:\xampp-php-7.3\htdocs\www\WC-V4\upload.php(66): mysqli_stmt->execute() #1 {main} thrown in D:\xampp-php-7.3\htdocs\www\WC-V4\upload.php on line 66

              Alors que quand j'avais essayé, je mettais la valeur de $demande_id dans une session et cela fonctionnait bien mais si j'essaie sans session de cette façon, cela ne marche pas:

              <?php
              
              require 'controller/dbConfig.php';
              
                  if (!empty($_FILES)) {
                      $uploadsDir = 'uploads/';
                      $allowedFileType = ['jpg', 'png', 'jpeg', 'tiff', 'pdf', 'jfif', 'psd', 'doc', 'docx', 'xls', 'xlsx', 'ppt'];
                      $uniqueName = md5(uniqid(rand(), true));
                      $separator = '---';
              
                      $dateActuelle = $_POST['dateActuelle'];
                      $nom = $_POST['nom'];
                      $email = $_POST['email'];
                      $telephone = $_POST['telephone'];
                      $adresse = $_POST['adresse'];
                      $ville = $_POST['ville'];
                      $cp = $_POST['cp'];
                      if (isset($_POST['radio'])) {
                          $ddeConcerne = $_POST['radio'];
                      } else {
                          $ddeConcerne = '';
                      }
                      if (isset($_POST['checkbox'])) {
                          $fonctionnalites = $_POST['checkbox'];
                      } else {
                          $fonctionnalites = '';
                      }
                      $message = $_POST['message'];
              
                      // INSERTION CLIENT
                      $sql1 = 'INSERT INTO clients (nom, email, telephone, adresse, ville, cp) VALUES  (?,?,?,?,?,?)';
                      if ($stmt = $conn->prepare($sql1)) {
                          $stmt->bind_param('ssssss', $nom, $email, $telephone, $adresse, $ville, $cp);
                          $stmt->execute();
                      }
              
                      // INSERTION DEMANDE
                      $client_id = $conn->insert_id;
                      $sql2 = 'INSERT INTO demandes (date_dde, client_id, ddeConcerne, fonctionnalites, message) VALUES  (?,?,?,?,?)';
                      if ($stmt = $conn->prepare($sql2)) {
                          $stmt->bind_param('sisss', $dateActuelle, $client_id, $ddeConcerne, $fonctionnalites, $message);
                          $stmt->execute();
                      }
              
                      // VERIFICATION FICHIERS
                      if (!empty(array_filter($_FILES['file']['name']))) {
                          foreach ($_FILES['file']['name'] as $id => $val) {
                              $fileName = $_FILES['file']['name'][$id];
                              $tempFile = $_FILES['file']['tmp_name'][$id];
                              $targetFilePath = $uploadsDir.$uniqueName.$separator.$fileName;
                              $fileType = strtolower(pathinfo($targetFilePath, PATHINFO_EXTENSION));
                              $uploadDate = date('Y-m-d H:i:s');
              
                              if (in_array($fileType, $allowedFileType)) {
                                  if (move_uploaded_file($tempFile, $targetFilePath)) {
                                      $sqlValFile = "('".$targetFilePath."', '".$uploadDate."')";
                                  }
                              }
              
                              // INSERTION DOCUMENTS
                              $demande_id = $conn->insert_id;
                              if (!empty($sqlValFile)) {
                                  $sql = 'INSERT INTO documents (demande_id, file_path) VALUES  (?,?)';
                                  if ($stmt = $conn->prepare($sql)) {
                                      $stmt->bind_param('is', $demande_id, $targetFilePath);
                                      $stmt->execute();
                                  }
                              }/*if (!empty($sqlValFile)) {*/
                          }/*foreach*/
                      }/*if (!empty(array_filter($_FILES['file']['name']))) {*/
                  }/*if (!empty($_FILES)) {*/
              
              $stmt->close();
              $conn->close();
              



              • Partager sur Facebook
              • Partager sur Twitter
                1 mars 2021 à 16:48:27

                Il faut récupérer l'id directement après l'insert, là il est écrasé dans ta boucle foreach documents ...

                Au passage, si c'est du PDO, pas besoin du $stmt->close() ... c'est fait d'office par PHP en fin de script.

                <?php
                require 'controller/dbConfig.php';
                
                if (!empty($_FILES)) {
                	$uploadsDir = 'uploads/';
                	$allowedFileType = ['jpg', 'png', 'jpeg', 'tiff', 'pdf', 'jfif', 'psd', 'doc', 'docx', 'xls', 'xlsx', 'ppt'];
                	$uniqueName = md5(uniqid(rand(), true));
                	$separator = '---';
                	
                	$dateActuelle = $_POST['dateActuelle'];
                	$nom = $_POST['nom'];
                	$email = $_POST['email'];
                	$telephone = $_POST['telephone'];
                	$adresse = $_POST['adresse'];
                	$ville = $_POST['ville'];
                	$cp = $_POST['cp'];
                	
                	if (isset($_POST['radio'])) {
                		$ddeConcerne = $_POST['radio'];
                	} else {
                		$ddeConcerne = '';
                	}
                	if (isset($_POST['checkbox'])) {
                		$fonctionnalites = $_POST['checkbox'];
                	} else {
                		$fonctionnalites = '';
                	}
                	$message = $_POST['message'];
                	
                	// INSERTION CLIENT
                	$sql1 = 'INSERT INTO clients (nom, email, telephone, adresse, ville, cp) VALUES (?,?,?,?,?,?)';
                	if ($stmt = $conn->prepare($sql1)) {
                		$stmt->bind_param('ssssss', $nom, $email, $telephone, $adresse, $ville, $cp);
                		$stmt->execute();
                		$client_id = $conn->insert_id;
                	}
                	
                	// INSERTION DEMANDE
                	$sql2 = 'INSERT INTO demandes (date_dde, client_id, ddeConcerne, fonctionnalites, message) VALUES (?,?,?,?,?)';
                	if ($stmt = $conn->prepare($sql2)) {
                		$stmt->bind_param('sisss', $dateActuelle, $client_id, $ddeConcerne, $fonctionnalites, $message);
                		$stmt->execute();
                		$demande_id = $conn->insert_id;
                	}
                	
                	// VERIFICATION FICHIERS
                	if (!empty(array_filter($_FILES['file']['name']))) {
                		foreach ($_FILES['file']['name'] as $id => $val) {
                			$fileName = $_FILES['file']['name'][$id];
                			$tempFile = $_FILES['file']['tmp_name'][$id];
                			$targetFilePath = $uploadsDir.$uniqueName.$separator.$fileName;
                			$fileType = strtolower(pathinfo($targetFilePath, PATHINFO_EXTENSION));
                			$uploadDate = date('Y-m-d H:i:s');
                			
                			if (in_array($fileType, $allowedFileType)) {
                				if (move_uploaded_file($tempFile, $targetFilePath)) {
                					$sqlValFile = "('".$targetFilePath."', '".$uploadDate."')";
                				}
                			}
                
                			// INSERTION DOCUMENTS
                			if (!empty($sqlValFile)) {
                				$sql = 'INSERT INTO documents (demande_id, file_path) VALUES (?,?)';
                				if ($stmt = $conn->prepare($sql)) {
                					$stmt->bind_param('is', $demande_id, $targetFilePath);
                					$stmt->execute();
                				}
                			}
                		}
                	}
                }

                -
                Edité par Benzouye 1 mars 2021 à 16:50:34

                • Partager sur Facebook
                • Partager sur Twitter
                Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                  1 mars 2021 à 18:17:35

                  Merci cela fonctionne bien. Ce n'est pas PDO mais MySQLi
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Cannot add or update a child row: a foreign key co

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown