Partage
  • Partager sur Facebook
  • Partager sur Twitter

insert, recherche max(id) et erreur sur update

    15 novembre 2019 à 1:57:13

    Bonjour,

    j'ai ce code qui me donne une erreur, apparemment sur la dernière requête et je ne comprend pas pourquoi, parce que dans phpmyadmin les requêtes fonctionnent. C'est donc un problème de variables mais laquelle ?

    require_once('fonctions/connectpdo.php');
    foreach($fonctionidadherent as $valc)
    {
    $modif2 = $bdd->prepare("INSERT IGNORE INTO A_Affect_Fonctions VALUES ('', :sc, :valc,'')");
    $modif2->execute(array('sc'=>$sc, 'valc'=>$valc));
    $last_id = $bdd->query("SELECT MAX(id_affect_fonct) AS maxid FROM A_Affect_Fonctions"); //recupération id dernier enregistrement 
    $reponse = $last_id->fetch();
    $modif3 = $bdd->prepare("UPDATE A_Adherents SET id_affect_fonction = :maxid WHERE id_adherent = :valc"); // report de l'id max dans table A_Adherents
    $modif3 = execute(array('maxid'=>$reponse['maxid'], 'valc'=>$valc));
    }
    Call to undefined function execute()... on line 9

    Si vous pouvez m'aiguiller, je vous en serais reconnaissant

    • Partager sur Facebook
    • Partager sur Twitter

    Ce qui se conçoit bien s'énonce clairement.

      15 novembre 2019 à 2:06:39

      $modif3->execute pas execute tout seul, d'où le message d'ereur qui parle bien de fonction et non de méthode.

      Les requêtes se préparent avant une boucle, pas dedans et le SELECT MAX c'est vraiment boiteux (surtout avec un INSERT IGNORE). Une transaction pour le tout ?

      -
      Edité par julp 15 novembre 2019 à 2:27:10

      • Partager sur Facebook
      • Partager sur Twitter
        15 novembre 2019 à 3:09:44

        julp a écrit:

        $modif3->execute pas execute tout seul, d'où le message d'ereur qui parle bien de fonction et non de méthode.



        Oh purée, pourquoi ne l'ai-je pas vu ?!!! Merci

        julp a écrit:

        Les requêtes se préparent avant une boucle, pas dedans et le SELECT MAX c'est vraiment boiteux (surtout avec un INSERT IGNORE). Une transaction pour le tout ?

        -
        Edité par julp il y a 33 minutes


        en fait je me suis rendu compte tout à l'heure que je n'avais pas besoin d'insérer cet id dans ma table A_Adherents (il se fait tard,lol)

        mais parce que ça peut peut-être me servir plus tard, pourquoi boiteux ?  quand aux prepare, j'aurais donc du les faire avant la boucle foreach et faire les execute après, c'est ça ?

        • Partager sur Facebook
        • Partager sur Twitter

        Ce qui se conçoit bien s'énonce clairement.

          15 novembre 2019 à 11:51:41

          > quand aux prepare, j'aurais donc du les faire avant la boucle foreach et faire les execute après, c'est ça ?

          Oui !

          > mais parce que ça peut peut-être me servir plus tard, pourquoi boiteux ?

          Déjà, ce n'est pas logique : tu fais un INSERT IGNORE = qui peut n'avoir rien inséré. Qu'est-ce que le SELECT MAX derrière peut bien renvoyer et en quoi ce qu'il renvoie (ou non aussi !) pourrait bien être cohérent ? En quoi il pourrait renvoyer ce que tu attends ? Si tu as besoin de la valeur attribuée à un auto increment, tu utilises PDO::lastInsertId, sûrement pas un SELECT MAX : si quelqu'un fait un INSERT dans la même table entre ton INSERT et ton SELECT MAX, tu te retrouves avec un id faux ...

          -
          Edité par julp 15 novembre 2019 à 11:53:49

          • Partager sur Facebook
          • Partager sur Twitter
            15 novembre 2019 à 13:14:28

            ben, vu que ces requêtes c'est pour gérer une interface d'administration avec un seul utilisateur, ça ne devrait pas arriver...

            Mais bon...

            donc mon code devrait être:

            require_once('fonctions/connectpdo.php');
            $modif2 = $bdd->prepare("INSERT IGNORE INTO A_Affect_Fonctions VALUES ('', :sc, :valc,'')");
            $modif3 = $bdd->prepare("UPDATE A_Adherents SET id_affect_fonction = :id_af WHERE id_adherent = :valc");
            foreach($fonctionidadherent as $valc)
            {
            $modif2->execute(array('sc'=>$sc, 'valc'=>$valc));
            $id_af = $bdd->lastInsertId();//recupération id dernier enregistrement
            $modif3 = execute(array('id_af'=>$id_af, 'valc'=>$valc));
            }


            Cette table A_Affect_Fonctions, est une table intermédiaire composée de 3 champs: id_affect_fonction, id_adherent, id_fonction, qui permet d'enregistrer les fonctions d'un adhérent (lequel peut en avoir plusieurs), le IGNORE,je l'utilise ainsi pour éviter les doublons à l'insert: je mets  les champs concernés (id_fonction et id_adherent) en clé unique, puis je fais un UN INSERT IGNORE pour que les post en erreur ne soient pas insérés et que l'erreur éventuelle ne bloque pas la requête...
            C'est boiteux ?

            • Partager sur Facebook
            • Partager sur Twitter

            Ce qui se conçoit bien s'énonce clairement.

              15 novembre 2019 à 13:28:53

              Sauf que tu fais un UPDATE quand l'INSERT IGNORE peut n'avoir rien fait, ce que tu ne testes pas avant de faire ton INSERT. (en tel cas, tu vas sans doute te retrouver avec 0 et une erreur si id_affect_fonction est bien une clé étrangère - bon, ok, si on compte sur cette erreur, on ne peut pas se retrouver avec n'importe quoi en base mais quand même)

              Sinon tu as répété l'erreur sur l'execute.

              Pour un auto incrément, évite '' et préfère NULL ou DEFAULT si vraiment tu ne veux pas préciser les colonnes en omettant l'id parce qu'avec un sql_mode strict, tu vas te manger une erreur.

              -
              Edité par julp 15 novembre 2019 à 13:33:56

              • Partager sur Facebook
              • Partager sur Twitter
                15 novembre 2019 à 14:27:04

                Ah oui effectivement, il vaudrait mieux que je fasse comme ça:

                require_once('fonctions/connectpdo.php');
                $modif2 = $bdd->prepare("INSERT IGNORE INTO A_Affect_Fonctions VALUES (NULL, :sc, :valc)");
                $modif3 = $bdd->prepare("UPDATE A_Adherents SET id_affect_fonction = :id_af WHERE id_adherent = :valc");
                foreach($fonctionidadherent as $valc)
                {
                $modif2->execute(array('sc'=>$sc, 'valc'=>$valc));
                if (isset($modif2)) 
                {
                $id_af = $bdd->lastInsertId();//recupération id dernier enregistrement
                $modif3 = execute(array('id_af'=>$id_af, 'valc'=>$valc));
                }
                }



                -
                Edité par thezig 15 novembre 2019 à 14:28:44

                • Partager sur Facebook
                • Partager sur Twitter

                Ce qui se conçoit bien s'énonce clairement.

                  15 novembre 2019 à 14:34:27

                  Sauf que ça ne fonctionnerait pas : isset d'une instance PDOStatement, ça sera forcément vrai.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    15 novembre 2019 à 14:44:20

                    Ah...j'ai toujours eu un problème avec les isset et autres empty

                    peut-être plutôt ceci ? 

                    if ($modif2!=FALSE)



                    -
                    Edité par thezig 15 novembre 2019 à 16:11:58

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Ce qui se conçoit bien s'énonce clairement.

                      15 novembre 2019 à 15:13:28

                      thezig a écrit:

                      Ah...j'ai toujours eu un problème avec les isset et autres empty

                      peut-être plutôt ceci ? 

                      if ($modif2!=FALSE)



                      -
                      Edité par thezig il y a 25 minutes

                      Et en regardant la doc tu auras ta réponse ;)

                      • Partager sur Facebook
                      • Partager sur Twitter
                        15 novembre 2019 à 16:13:05

                        Damned, j'ai encore utilisé = au lieu de ==

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Ce qui se conçoit bien s'énonce clairement.

                          15 novembre 2019 à 16:18:40

                          non ici != <=> "différend de" c'est bon. Par contre si tu hésites sur ça, relis un peu les bases des comparaisons ;)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            15 novembre 2019 à 16:32:56

                            Toujours l'erreur sur l'execute.

                            Non, tu compares toujours une instance PDOStatement à un scalaire, ce qui n'a pas vraiment de sens (le test sera toujours faux ou vrai suivant la condition qui s'en retrouve inutile). Ce n'est pas ton instance PDOStatement qu'il faut comparer. Il faut savoir si tu as inséré quelque chose ou pas, donc c'est le résultat de $modif2->rowCount() qu'il fau(drai)t tester.

                            Eventuellement si $bdd->lastInsertId() renvoie '0' mais rowCount est plus "sûre" et surtout portable.

                            Si tu es du genre à avoir besoin de visualiser ce que tu as, fais un var_dump de ta variable. Après, il faut aussi se poser des questions : est-ce que comparer des choux et des carottes, ça a un sens ? Et, puis, si tu veux vérifier quelque chose, fais-le test : arrange-toi pour que l'INSERT IGNORE ne fasse rien et observe ce qu'il se passe avec l'UPDATE (et inversement, quand l'INSERT IGNORE a bien réalisé une insertion).

                            -
                            Edité par julp 15 novembre 2019 à 16:40:29

                            • Partager sur Facebook
                            • Partager sur Twitter

                            insert, recherche max(id) et erreur sur update

                            × 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