IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Procédural MySQL Discussion :

Mysql5, Procédure stockée et PDO::LastInsertId()


Sujet :

SQL Procédural MySQL

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Janvier 2006
    Messages : 43
    Points : 43
    Points
    43
    Par défaut Mysql5, Procédure stockée et PDO::LastInsertId()
    Bonjour à vous tous,

    J'ai un petit souci avec la méthode PDO::LastInsertId() et MySQL5.
    J'enregistre des données dans une table avec un id autoincrémenté et j'aimerais bien récupérer le dernier Id. Ceci me permettait d'utiliser cet Id pour l'insérer dans une table de liaison.
    Quand j'utilise une requête INSERT classique, LastInsertId() me retourne bien le dernier Id inséré dans la table.
    - PDO avec requête INSERT classique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $connectBDD = new PDO($dsn, $login, $mdp);
    $insert ="INSERT INTO table(champ1, champ2) VALUES ('valeur1', 'valeur2');
    $test = $connectBDD->exec($insert);
    print $connectBDD->lastInsertId();
    $connectBD=null;
    Par contre en remplaçant cette requête par une procédure stockée, LastInsertId() me retourne 0
    - Procédure Stockée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    DELIMITER $$
    CREATE PROCEDURE `database`.`InsertProcedure`(
      IN inChamp1 INT(2),
      IN inChamp2 VARCHAR(50))
    BEGIN
      INSERT INTO table(
      champ1,
      champ2
    )
    VALUES(
      inChamp1,
      inChamp2
    );
    END $$
    DELIMITER ;
    - PDO avec Procédure Stockée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $connectBDD = new PDO($dsn, $login, $mdp);
    $insert ="CALL InsertProcedure('valeur1', 'valeur2')";
    $test = $connectBDD->exec($insert);
    print $connectBDD->lastInsertId();
    $connectBDD=null;
    D'où vient le problème ? De la déclaration de ma procédure stockée ? Ou du fait que PDO::LastInsertId() ne fonctionne pas avec une procédure stockée ?

    Merci de m'éclairer sur ce point. Il serait dommage que je ne puisse pas utiliser mes procédures stockées dans mon projet.

  2. #2
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Janvier 2006
    Messages : 43
    Points : 43
    Points
    43
    Par défaut
    Que les experts en PDO se manifestent ...

  3. #3
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Essaie d'affecter la valeur de last_insert_id() à une variable de sortie dans ta procédure...
    Pensez au bouton

  4. #4
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Janvier 2006
    Messages : 43
    Points : 43
    Points
    43
    Par défaut
    En faisant ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    DELIMITER $$
    CREATE PROCEDURE `database`.`InsertProcedure`(
      IN inChamp1 INT(2),
      IN inChamp2 VARCHAR(50),
      OUT lastID INT(2))
    BEGIN
      INSERT INTO table(
      champ1,
      champ2
    )
    VALUES(
      inChamp1,
      inChamp2
    );
    SET lastID = LAST_INSERT_ID();
    END $$
    DELIMITER ;
    Par contre, je ne sais pas comment récupérer cette variable de sortie avec la syntaxe PDO?

  5. #5
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Avec une variable de session MySQL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $insert ="CALL InsertProcedure('valeur1', 'valeur2', @lastinsert)";
    $test = $connectBDD->exec($insert);
    $last="SELECT @lastinsert";
    ...
    Pensez au bouton

  6. #6
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Janvier 2006
    Messages : 43
    Points : 43
    Points
    43
    Par défaut
    Je viens de tester à l'instant, et cela fonctionne (je n'en douté pas).
    Pour résumé, cela donne cela alors :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $connectBDD = new PDO($dsn, $login, $mdp);
    $insert ="CALL InsertProcedure('valeur1', 'valeur2', @lastinsert)";
    $test = $connectBDD->exec($insert);
    $resultat = $connectBDD->query("SELECT @lastinsert");
    $lastId = $resultat->fetch();
    echo $lastId[0];
    $connectBDD=null;
    Est-qu'en terme de performance, cela n'est pas néfaste ? Il n'y a pas moyen d'optimiser ceci ? Si j'ai bien compris PDO::LastInsertId() ne fonctionne pas avec les procédures stockées. C'est plutôt dommange...

    Merci à toi pour tes lumières

  7. #7
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Citation Envoyé par Philsmile
    Est-qu'en terme de performance, cela n'est pas néfaste ?
    Pas spécialement. Tu peux toujours essayer de faire le SELECT @lastinsert à la fin de la procédure elle-même, ce qui économisera une requête et un aller retour client-serveur. Par contre ça peut entrainer des problèmes, cf http://www.developpez.net/forums/vie...=given+context

    Citation Envoyé par Philsmile
    Si j'ai bien compris PDO::LastInsertId() ne fonctionne pas avec les procédures stockées. C'est plutôt dommange...
    Je pense que ça n'a pas de rapport avec PDO. A un moment j'avais testé le SELECT LAST_INSERT_ID() à l'extérieur de la procédure stockée et il me semble que ça fonctionnait uniquement avec certaines versions de MySQL 5.
    Pensez au bouton

  8. #8
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Janvier 2006
    Messages : 43
    Points : 43
    Points
    43
    Par défaut
    Merci pour tes réponses, tu as su m'éclairer.

    Voila ce que cela donne pour la Procédure Stockée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    DELIMITER $$
    CREATE PROCEDURE `database`.`InsertProcedure`(
      IN inChamp1 INT(2),
      IN inChamp2 VARCHAR(50),
      OUT lastID INT(2))
    BEGIN
      INSERT INTO table(
      champ1,
      champ2
    )
    VALUES(
      inChamp1,
      inChamp2
    );
    SET lastID = LAST_INSERT_ID();
    SELECT lastID;
    END $$
    DELIMITER ;
    Et pour PDO avec la Procédure Stockée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $connectBDD = new PDO($dsn, $login, $mdp);
    $insert ="CALL InsertProcedure('valeur1', 'valeur2', @lastID)";
    $resultat = $connectBDD->query($insert);
    $tabResultat = $resultat->fetch();
    echo $tabResultat['lastID'];
    $connectBDD=null;
    Voilà, en espérant que cela aidera d'autres personnes :o

  9. #9
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Janvier 2006
    Messages : 43
    Points : 43
    Points
    43
    Par défaut Et lorsque l'on enchaîne deux procédures de ce type
    Maintenant j'ai bien avancé dans mon projet mais les problèmes se déplacent (ou c'est plutôt mon manque d'expérience qui fait surface...)

    J'essaie d'enchaîner deux procédures de ce type. Je m'explique.
    - j'ai une première procédure qui me permet de créer un terrain et de récupérer son id (id_terrain)
    - j'ai une deuxième procédure qui me permet de créer une personne et de récupérer son id (id_personne)
    Le but de cette opération est d'insérer ces deux id (id_terrain et id_personne) dans une table de liaison (table vendeur).

    Donc j'ai comme code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $connectBDD = new PDO($dsn, $login, $mdp);
    $connectBDD->beginTransaction();
    $insertTerrain ="CALL InsertTerrain('valeur1', 'valeur2', @lastID)";
    $insertVendeur ="CALL InsertVendeur('valeur1', 'valeur2', @lastID)";
     
    $resultatTerrain = $connectBDD->query($insertTerrain);
    $tabResultatTerrain = $resultatTerrain->fetch();
    echo $tabResultatTerrain['lastID'];
     
    $resultatVendeur = $connectBDD->query($insertVendeur);
    $tabResultatVendeur = $resultatVendeur->fetch();
    echo $tabResultatVendeur['lastID'];
    $connectBDD->commit();
     
    $connectBDD=null;
    Mais quand j'enchaîne ces deux procédures j'ai une erreur de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
    J'ai l'impression qu'il manque une commande entre les deux exécutions des procédures mais laquelle ? J'ai beau regardé la doc de PDO, je ne vois pas...

  10. #10
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Janvier 2006
    Messages : 43
    Points : 43
    Points
    43
    Par défaut
    J'ai rajouté ceci à l'instanciation de mon objet PDO :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $connectBDD = new PDO($dsn, $login, $mdp, array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=>true ))
    Et cela fonctionne. Mais je n'ai pas trouvé de réelle explication à PDO::MYSQL_ATTR_USE_BUFFERED_QUERY. Quel est son but ? Quelle en est l'incidence en terme de performance ? Enfin bref, j'aimerais bien savoir si ce que je fais est juste et nécessaire.

    Merci d'avance pour vos remarques

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 25
    Points : 23
    Points
    23
    Par défaut
    bonjour, j'ai exactement le meme probleme, mais sur une requete toute simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Array ( [0] => HY000 [1] => 2036 [2] => )
    Erreur select:
    SELECT temps, ladate FROM TRAVAILLER t, POLE p, UTILISATEUR u WHERE p.ID_POLE='1' AND u.ID_UTIL='6' AND t.LADATE BETWEEN '2006-04-01' AND '2006-04-31' AND p.id_pole=t.id_pole AND u.id_util=t.id_util
    J'ai rajouter le PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
    A tu trouvé à quoi sert ce parametre?

    a+

  12. #12
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Janvier 2006
    Messages : 43
    Points : 43
    Points
    43
    Par défaut
    Effectivement, en lisant la doc PDO, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY utilise les requêtes beuffeurisées.

    Même après quelques recherche, je n'ai pas eu de réponse explicite.

    Si quelqu'un pouvait nous éclairer ....

Discussions similaires

  1. [PDO] Procédures stockées et PDO
    Par Madfrix dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 24/12/2010, 11h38
  2. [PDO] [PHP 5.3][ZEND][PDO] Exécution d'une procédure stockée via PDO et Zend
    Par daav14 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 11/10/2010, 20h56
  3. PHP5/MySQL5 : procédures stockées
    Par zyongh dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 06/01/2009, 12h24
  4. [MySQL5] Procédures Stockées de Mise à jour
    Par Shinn77 dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 26/10/2007, 14h17
  5. [MySQL5] Procédure Stockée et RollBack
    Par filouxera dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 12/03/2006, 19h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo