Partage
  • Partager sur Facebook
  • Partager sur Twitter

Première requête SQL imbriquée en PHP

    20 mai 2022 à 17:10:00

    Bonjour,

    J'essaie de faire une page pour gérer mon compte bancaire

    J'aimerai une requête imbriquée qui remplirait la base si la ligne n'existe pas déjà.

    Quelqu'un aurait-il la solution svp?

    Les données qui rentrent ressemblent à ca 

    Array
    (
        [operation6] => Array
            (
                [date] => 09-05-2022
                [Designation] => PAIEMENT PAR CARTE aliexpress Luxembourg      08/05  
                [Debit] => 4,63
                [Credit] => 
            )
     

    Ca fait deux jours que je bloque dessus voilà où j'en suis :/

     $l = 0;
     $sql = $db->prepare("INSERTINTO `operationsCpt07585128000` (`Date`,`DateDB`,`Designation`,`Debit`,`Credit`)
    VALUES (:Date,:DateDB,:Designation,:Debit,:Credit)
    FROM operationsCpt07585128000
    WHERENOTEXISTS ( SELECTDate,Designation,Debit,Credit
    FROM operationsCpt07585128000 WHEREDate= :DateAND Designation = :Designation AND Debit = :Debit AND Credit = :Credit
                            )");
    while (isset($csvToArray['operation' . $l])) {
        $sql->execute([
                'Date' => $csvToArray['operation' . $l]['date'],
                'DateDB' => time(),
                'Designation' => $csvToArray['operation' . $l]['Designation'],
                'Debit' => $csvToArray['operation' . $l]['Debit'],
                'Credit' => $csvToArray['operation' . $l]['Credit']
        ]);
        $donnee = $sql->fetchAll();
        $l++;
        }
    j'ai actuellement l'erreur: 
    Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064

    -
    Edité par david || 0 20 mai 2022 à 17:13:32

    • Partager sur Facebook
    • Partager sur Twitter
      20 mai 2022 à 18:12:30

      Bonjour,

      Où as-tu trouvé cette syntaxe d'INSERT ? Cela ne peut pas fonctionner ...

      david || 0 a écrit:

      J'aimerai une requête imbriquée qui remplirait la base si la ligne n'existe pas déjà

      Plusieurs possibilités.

      La plus simple selon moi, c'est de mettre une contrainte UNIQUE( Date, Designation, Debit, Credit ) sur la table operationsCpt07585128000, Puis de faire un INSERT IGNORE :

      INSERT IGNORE INTO `operationsCpt07585128000` ( `Date`, `DateDB`, `Designation`, `Debit`, `Credit` )
      VALUES ( :Date, NOW(), :Designation, :Debit, :Credit )

      Si tu essayes d'insérer une données qui existe déjà, une erreur SQL sera levée, l'insertion ne fonctionnera pas mais le script continuera ...

      A peine plus compliqué, de faire ta requête en deux temps :

      $l = 0;
      
      $sqlTest = $db->prepare( '
      	SELECT 1
      	FROM `operationsCpt07585128000`
      	WHERE
      		Date= :Date
      		AND Designation = :Designation
      		AND Debit = :Debit
      		AND Credit = :Credit'
      );
      
      $sqlInsert = $db->prepare("
      	INSERT INTO `operationsCpt07585128000` ( `Date`, `DateDB`, `Designation`, `Debit`, `Credit` )
      	VALUES ( :Date, NOW(), :Designation, :Debit, :Credit )"
      );
      
      while( isset( $csvToArray['operation' . $l] ) ) {
      	
      	$sqlTest->execute( $csvToArray['operation' . $l] );
      	$existe = $sqlTest->fetchAll();
      	if( $existe ) $sqlInsert->execute( $csvToArray['operation' . $l] );
      	$l++;
      }

      Après, une question me titille sur le format des données d'entrée ... Pourquoi avoir numéroté les index "operationX" au lieu d'un simple tableau comme ceci :

      Array (
          [0] => Array (
              [date] => 09-05-2022
              [Designation] => PAIEMENT PAR CARTE aliexpress Luxembourg      08/05 
              [Debit] => 4,63
              [Credit] =>
          ),
          [1] => Array (
              [date] => 09-05-2022
              [Designation] => PAIEMENT PAR CARTE aliexpress Luxembourg      08/05 
              [Debit] => 4,63
              [Credit] =>
          ),
          [2] => Array (
              [date] => 09-05-2022
              [Designation] => PAIEMENT PAR CARTE aliexpress Luxembourg      08/05 
              [Debit] => 4,63
              [Credit] =>
          ),
      ...

      Au lieu de ta variable $l et de ta boucle while tu aurais juste un foreach à faire ... genre :

      foreach( $csvToArray as $operation ) {
          $sqlTest->execute( $operation );
          $existe = $sqlTest->fetchAll();
          if( $existe ) $sqlInsert->execute( $operation );
      }

      -
      Edité par Benzouye 20 mai 2022 à 18:17:04

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        20 mai 2022 à 18:33:14

        Merci Benzouye par ta réponse complète et très rapide.

        J'ai regarder rapidement IGNORE mais j'aurai des lignes identiques tous les mois (certains prélèvements), je compte affiner la requête par la suite.

        Je vais prendre ta solution en deux requêtes, elle est plus clair et elle fonctionne :)

        Pour mon tableau source, je vais essayer de simplifier la hiérarchie et passer par un foreach

        Merci encore

        • Partager sur Facebook
        • Partager sur Twitter
          20 mai 2022 à 19:02:48

          david || 0 a écrit:

          j'aurai des lignes identiques tous les mois (certains prélèvements)

          La date sera différente j'espère... sinon c'est incohérent... Le contrôle avec UNIQUE sera le même qu'avec la double requête... et il est plus rigoureux de faire porter l'intégrité des données par la base de données que par l'application...
          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL

          Première requête SQL imbriquée en PHP

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          • Editeur
          • Markdown