Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 23/03/2006, 13h57   #1
Nouveau Membre du Club
 
Inscription : janvier 2006
Messages : 43
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2006
Messages : 43
Points : 25
Points : 25
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 :
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 :
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 :
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.
Philsmile est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2006, 15h55   #2
Nouveau Membre du Club
 
Inscription : janvier 2006
Messages : 43
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2006
Messages : 43
Points : 25
Points : 25
Que les experts en PDO se manifestent ...
Philsmile est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2006, 16h06   #3
Provisoirement toléré
 
Avatar de Maximilian
 
Inscription : juin 2003
Messages : 2 622
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 2 622
Points : 2 505
Points : 2 505
Essaie d'affecter la valeur de last_insert_id() à une variable de sortie dans ta procédure...
__________________
Pensez au bouton
Maximilian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2006, 16h29   #4
Nouveau Membre du Club
 
Inscription : janvier 2006
Messages : 43
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2006
Messages : 43
Points : 25
Points : 25
En faisant ainsi :
Code :
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?
Philsmile est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2006, 16h36   #5
Provisoirement toléré
 
Avatar de Maximilian
 
Inscription : juin 2003
Messages : 2 622
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 2 622
Points : 2 505
Points : 2 505
Avec une variable de session MySQL :

Code :
1
2
3
4
$insert ="CALL InsertProcedure('valeur1', 'valeur2', @lastinsert)";
$test = $connectBDD->exec($insert);
$last="SELECT @lastinsert";
...
__________________
Pensez au bouton
Maximilian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2006, 17h03   #6
Nouveau Membre du Club
 
Inscription : janvier 2006
Messages : 43
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2006
Messages : 43
Points : 25
Points : 25
Je viens de tester à l'instant, et cela fonctionne (je n'en douté pas).
Pour résumé, cela donne cela alors :
Code :
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
Philsmile est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2006, 17h25   #7
Provisoirement toléré
 
Avatar de Maximilian
 
Inscription : juin 2003
Messages : 2 622
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 2 622
Points : 2 505
Points : 2 505
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/viewtopic.php?t=471124&highlight=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
Maximilian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/03/2006, 09h25   #8
Nouveau Membre du Club
 
Inscription : janvier 2006
Messages : 43
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2006
Messages : 43
Points : 25
Points : 25
Merci pour tes réponses, tu as su m'éclairer.

Voila ce que cela donne pour la Procédure Stockée:
Code :
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 :
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
Philsmile est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/03/2006, 11h07   #9
Nouveau Membre du Club
 
Inscription : janvier 2006
Messages : 43
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2006
Messages : 43
Points : 25
Points : 25
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 :
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 :
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...
Philsmile est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/03/2006, 14h08   #10
Nouveau Membre du Club
 
Inscription : janvier 2006
Messages : 43
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2006
Messages : 43
Points : 25
Points : 25
J'ai rajouté ceci à l'instanciation de mon objet PDO :
Code :
$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
Philsmile est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/04/2006, 12h10   #11
Futur Membre du Club
 
Inscription : avril 2006
Messages : 25
Détails du profil
Informations personnelles :
Âge : 26

Informations forums :
Inscription : avril 2006
Messages : 25
Points : 18
Points : 18
bonjour, j'ai exactement le meme probleme, mais sur une requete toute simple

Code :
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+
SimMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/04/2006, 13h59   #12
Nouveau Membre du Club
 
Inscription : janvier 2006
Messages : 43
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2006
Messages : 43
Points : 25
Points : 25
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 ....
Philsmile est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h37.


 
 
 
 
Partenaires

Hébergement Web