MySQL - Comment avoir la prochaine valeur d'un increment?? - PHP - Programmation
Marsh Posté le 05-10-2002 à 19:19:39
t sur ca me parait bizarre
ou ya toujours un astuce bidon : tu ajoute une nouvelle ligne vide et ta directement le id
Marsh Posté le 05-10-2002 à 20:07:12
cf la doc
If you insert a record in a table containing a column that has the AUTO_INCREMENT attribute, you can get the most recently generated ID by calling the mysql_insert_id() function. |
Marsh Posté le 05-10-2002 à 20:20:02
ou un select max(id)
Marsh Posté le 06-10-2002 à 00:41:59
Le fait de trouver la valeur la plus grande du champ auto_increment n'est pas suffisant car si tu elle est de 12, et que tu supprime les 2 derniers enregistrements (11 et 12), ta nouvelle valeur la plus grande sera 10, et tu penseras que la prochaine valeur sera 11, alors qu'elle sera 13 !
donc la solution consiste à prendre la dernière valeur incrémentée lors d'un ajout, cad:
après l'exécution de la requête ajout, écrire:
$id_max = mysql_insert_id ();
tu sauras à chaque instant que la prochaine sera:
$prochaine = $max_id + 1;
Voilà !
Marsh Posté le 06-10-2002 à 00:45:04
Ou alors t'as une autre solution qui consiste à faire un count des enregistrements de ta base et d'y ajouter 1
Marsh Posté le 06-10-2002 à 00:52:29
Format_C a écrit a écrit : Ou alors t'as une autre solution qui consiste à faire un count des enregistrements de ta base et d'y ajouter 1 |
Ben non, c'est une mauvaise méthode, pour les raisons que j'ai données plus haut !
Marsh Posté le 06-10-2002 à 00:58:09
sweedy a écrit a écrit : Ben non, c'est une mauvaise méthode, pour les raisons que j'ai données plus haut ! |
Je vois pas en quoi un Count ne permettrait pas de retourner le Nbre d'enregistrement (pas l'ID de l'auto increment) d'une table ?
C'est bien le pb de sa question non ?
Edit : AU passage avec ta solution tu lui recrées le même pb mais codé différemment
Marsh Posté le 06-10-2002 à 01:03:08
haazheel a écrit a écrit : Je m'explique: dans une bdd, j'ai un champ id en auto_increment... Je voudrais avoir la prochaine valeur de ce champ. Alors j'ai fait un max(id) as id que j'incrémente de 1, ce qui me donne la prochaine valeur. Mais le problème est que lorsque j'ai déjà enregistré, disons 24 valeurs, et que je les efface toutes, la prochaine valeur de id sera 25... Mais avec le max(id), ben j'aurai 1, car le max(id) me donnera 0 comme valeur. Comment je peux faire alors?? |
je crois que y a aps de solution, la meilleur methode, c est soit d inserer avant et faire apres un update de la ligne.
soit de faire un fichier "ma_table.id" dasn laquel tu stock le dernier id (a chaque insertion) -> c'est surment pas mal...
Marsh Posté le 06-10-2002 à 01:07:39
Voila une solution :
$sql = 'SELECT COUNT(*) AS compte FROM Tatable' ;
$result = mysql_query($sql)
$data = mysql_fetch_array($result) ;
echo $data['compte'];
Si les 2 rigolos qui se foutent de moi plus haut ont mieux... je suis preneur
Marsh Posté le 06-10-2002 à 01:13:52
slvn a écrit a écrit : je crois que y a aps de solution, la meilleur methode, c est soit d inserer avant et faire apres un update de la ligne. soit de faire un fichier "ma_table.id" dasn laquel tu stock le dernier id (a chaque insertion) -> c'est surment pas mal... |
Non mais vous êtes tous fous ou quoi???
Relisez bien la question d'origine
La SEULE SOLUTION EN MYSQL est la suivante:
après chaque nouvelle insertion, on fait :
$maxid= mysql_insert_id();
et c'est tout ! count et max (id) ne marcheront jamais, sauf dans le rare cas où vous ne supprimez AUCUN enregistrement, donc c'est une méthode à banir...
(cf doc mysql)
Marsh Posté le 06-10-2002 à 01:16:00
sweedy a écrit a écrit : Non mais vous êtes tous fous ou quoi??? Relisez bien la question d'origine La SEULE SOLUTION EN MYSQL est la suivante: après chaque nouvelle insertion, on fait : $maxid= mysql_insert_id(); et c'est tout ! count et max (id) ne marcheront jamais, sauf dans le rare cas où vous ne supprimez AUCUN enregistrement, donc c'est une méthode à banir... (cf doc mysql) |
Et le rigolo !
Balance ça dans l'executeur de script d'easy php et regarde si ça te renvoie pas le nbr d'enregistrements : SELECT COUNT(*) AS compte FROM Tatable
Alors ?
Marsh Posté le 06-10-2002 à 01:22:22
Format_C a écrit a écrit : Voila une solution : $sql = 'SELECT COUNT(*) AS compte FROM Tatable' ; $result = mysql_query($sql) $data = mysql_fetch_array($result) ; echo $data['compte']; Si les 2 rigolos qui se foutent de moi plus haut ont mieux... je suis preneur |
Ah ben bravo, alos là je dis chapeau, tu ne pourras jamais être développeur de métier !
Pour me justifier, je te donne très vite un contre exemple:
dans ma table toto, j'ai disons 4 enregistrements dont le champ id qui nous intéresse à pour valeurs: 3,5,6 et 15.
j'ai eu également un 5ème enregistrement avec id=16, mais je l'ai supprimé.
donc ton $data qui a été généré grâce à un count va te donner 4, et tu vas donner la valeur 5 (4 + 1) à ton prochain enregistrement, alors que l'id du prochain enregistrement doit avoir pour valeur 17, simple non?
Ah c'est du propre, moi je vous le dis, y'en a un beau paquet sur le forum, qui vont se foutrent de votre geule !
Marsh Posté le 06-10-2002 à 01:23:46
Format_C a écrit a écrit : Et le rigolo ! Balance ça dans l'executeur de script d'easy php et regarde si ça te renvoie pas le nbr d'enregistrements : SELECT COUNT(*) AS compte FROM Tatable Alors ? |
Alors tu vas te cacher
Marsh Posté le 06-10-2002 à 01:28:40
Format_C a écrit a écrit : Et le rigolo ! Balance ça dans l'executeur de script d'easy php et regarde si ça te renvoie pas le nbr d'enregistrements : SELECT COUNT(*) AS compte FROM Tatable Alors ? |
Ben tu es hors sujet, si c'est à moi que tu parlais, ta requête est syntaxiquement bonne, mais elle ne répond pas du tout à la question, ce que tu as besoin en fait, c'est d'un cerveau pour comprendre la question... je ne t'agresse pas, mais j'aime pas trop les gens qui persistent dans leur erreur, et qui se permettent de traiter ceux qui donnent une bonne réponse de "rigolos", c'est tout, fin de la discussion.
Marsh Posté le 06-10-2002 à 01:29:33
Bon ok je suis déjà très très très loin, caché derrière un bosquet
J'ai lu le pb à l'envers
Je pensais que son pb était justement que si par ex il avait 20 enregistrements et qu'il en effacé 4, il voulait avoir comme résultat 16 et non pas 20.
C'est bon, trucidez moi je mérite
Marsh Posté le 06-10-2002 à 01:30:55
sweedy a écrit a écrit : Ben tu es hors sujet, si c'est à moi que tu parlais, ta requête est syntaxiquement bonne, mais elle ne répond pas du tout à la question, ce que tu as besoin en fait, c'est d'un cerveau pour comprendre la question... je ne t'agresse pas, mais j'aime pas trop les gens qui persistent dans leur erreur, et qui se permettent ceux qui donnent une bonne réponse de "rigolos", c'est tout, fin de la discussion. |
C'est pour ça que plus je t'avais demandé (sans réponse) si j'avais bien compris sa question...
Citation : |
Marsh Posté le 06-10-2002 à 01:34:32
Format_C a écrit a écrit : C'est bon, trucidez moi je mérite |
Avec plaisir, mais ca ne résouds pas son problème
Si tu supprimes tous les éléments de la table, le challenge c'est de savoir l'id du prochain généré sans en rajouter vu que ca modifierait le prochain id généré.
Mais faut voir si son problème peut pas être résolu autrement, et surtout pourquoi il en a besoin. Parole à l'auteur
Marsh Posté le 06-10-2002 à 01:38:22
zion a écrit a écrit : Avec plaisir, mais ca ne résouds pas son problème |
Donc vous n'appréciez pas ma méthode non plus, je ne vois pas bien quel est son défaut?
Marsh Posté le 06-10-2002 à 01:45:17
sweedy a écrit a écrit : Donc vous n'appréciez pas ma méthode non plus, je ne vois pas bien quel est son défaut? |
Je crois que ce qu'il veut dire c'est qu'avec l'insert(id), ça génèrerait un enregistrement dans la base et que donc si ton insert(id) te revoyait bien la prochaine valeur, en en insérant une, la prochaine valeur ne serait plus la prochaine, mais la prochaine+1.
C'est ça Zion ?
Marsh Posté le 06-10-2002 à 01:57:24
...........
en SQL, y a une fonction qui s appel : "LAST_INSERT_ID ()"
ca donne le dernier ID généré !! (on peux pas choisir la table)
par ex : on vient de faire une insertion,
on fait last_insert_id() => ca donne l'id qui a été crée!!
cette fonction, c est connu en php sous le nom de mysql_insert_id lorsqu'il s'agit de base mysql.
le pb de haazheel, c est qu'il veut savoir l'id avant de faire l'insert !
et ca c pas possible 'facilement' (ie sans regarder dans le fichier des table de mysql' )
donc la solution c est:
soit :
tu fais l'insert avant, et tu te debrouille avec l'id apres..(par ex en faisant un "update ... where id=$id" )
soit :
tu fais un fichier "*.txt" a la racine de ton site, qui memorise le dernier id inséré pour chacune des tables. (c pas pareil que le last_insert_id, car on peut regarde le fichier la table X sans que y ait eu une insert sur cette table )
voila...
Marsh Posté le 06-10-2002 à 02:01:03
Format_C a écrit a écrit : Je crois que ce qu'il veut dire c'est qu'avec l'insert(id), ça génèrerait un enregistrement dans la base et que donc si ton insert(id) te revoyait bien la prochaine valeur, en en insérant une, la prochaine valeur ne serait plus la prochaine, mais la prochaine+1. C'est ça Zion ? |
Benh oui, ici il veux pouvoir connaitre le prochain id même si la table est vide, et sans rajouter d'éléments, ce qui me semble à priori pas possible sans le stocker ailleurs, sauf si on peut demander un last_id pour une table précise (j'en doute).
Mais comme dis plus haut, faut qu'il explique le contexte, plutot que de trouver une solution fantaisiste, il est 99 fois sur 100 préférable de modifier le problème
Marsh Posté le 06-10-2002 à 02:03:31
zion a écrit a écrit : Benh oui, ici il veux pouvoir connaitre le prochain id même si la table est vide, et sans rajouter d'éléments, ce qui me semble à priori pas possible sans le stocker ailleurs, sauf si on peut demander un last_id pour une table précise (j'en doute). Mais comme dis plus haut, faut qu'il explique le contexte, plutot que de trouver une solution fantaisiste, il est 99 fois sur 100 préférable de modifier le problème |
Donc si il modifie son pb, ma solution était bonne !
Marsh Posté le 06-10-2002 à 02:11:57
Format_C a écrit a écrit : Donc si il modifie son pb, ma solution était bonne ! |
La tienne jamais de la vie
Marsh Posté le 06-10-2002 à 02:41:16
slvn a écrit a écrit : ........... en SQL, y a une fonction qui s appel : "LAST_INSERT_ID ()" ca donne le dernier ID généré !! (on peux pas choisir la table) par ex : on vient de faire une insertion, on fait last_insert_id() => ca donne l'id qui a été crée!! cette fonction, c est connu en php sous le nom de mysql_insert_id lorsqu'il s'agit de base mysql. le pb de haazheel, c est qu'il veut savoir l'id avant de faire l'insert ! et ca c pas possible 'facilement' (ie sans regarder dans le fichier des table de mysql' ) donc la solution c est: soit : tu fais l'insert avant, et tu te debrouille avec l'id apres..(par ex en faisant un "update ... where id=$id" ) soit : tu fais un fichier "*.txt" a la racine de ton site, qui memorise le dernier id inséré pour chacune des tables. (c pas pareil que le last_insert_id, car on peut regarde le fichier la table X sans que y ait eu une insert sur cette table ) voila... |
Je suis assez d'accord avec toi ! Sur ce, bonne nuit à tous.
Marsh Posté le 06-10-2002 à 02:43:49
phpMyAdmin l'indique, mais je ne sais pas comment il récupère la valeur.
Si quelqu'un a envie de décortiquer le script, ça m'intéresse aussi?
Marsh Posté le 06-10-2002 à 02:47:39
Freekill a écrit a écrit : phpMyAdmin l'indique, mais je ne sais pas comment il récupère la valeur. Si quelqu'un a envie de décortiquer le script, ça m'intéresse aussi? |
Comme le champ auto_increment est aussi un index, il doit sûrement lire dans le fichier d'index correspondant à id...
http://www.mysql.com/doc/en/InnoDB [...] ecord.html
Oh merde, j'ai dit que j'allais me coucher
Marsh Posté le 06-10-2002 à 10:39:26
zion a écrit a écrit : La tienne jamais de la vie |
Si si je suis sûr qu'il y a moyen de le convaincre d'inverser le pb
Marsh Posté le 06-10-2002 à 12:54:04
j'ai decortiqué un peu phpMyAdmin :
il apparait que ce que l'on cherche a faire est tout simple (encore faut il le connaire )
la requete a effectuer est : " SHOW TABLE STATUS LIKE 'ma_table' "
la ligne renvoyé contient un champs qui s'appelle "Auto_increment", et qui est le prochain index crée!
Marsh Posté le 06-10-2002 à 14:08:46
Oulà, que de réponses!!
Très instructif comme topic je trouve...
Le problème est que j'ai effectivement modifié mon script, de telle sorte à pouvoir me passer de l'auto_increment...
Je fais un max(id), j'incremente de 1, puis j'insère directement le id, ce qui donne:
Code :
|
Au lieu de:
Code :
|
Mais je vais me pencher sur la dernière solution évoquée, à savoir le SHOW TABLE STATUS LIKE 'ma_table'
Ce qui amène la question suivante: vaut-il mieux se passer d'un champ auto_increment, et utiliser ma méthode, ou bien au contraire en utiliser un, et choisir la dernière méthode?
Comme j'ai appris sur le tas, je ne sais pas ce qu'on préconise habituellement...
Merci à tous!!
Marsh Posté le 06-10-2002 à 14:37:08
haazheel a écrit a écrit : Ce qui amène la question suivante: vaut-il mieux se passer d'un champ auto_increment, et utiliser ma méthode, ou bien au contraire en utiliser un, et choisir la dernière méthode? |
Ben difficile à dire, en tous les cas je te donne 2 pistes:
- pour des raisons de portabilité, ta méthode d'incrémentation est meilleure car sache que le champ auto_increment n'est pas implémenté dans toutes les BDD (ex: interbase n'en a pas, Oracle non plus il me semble), donc cette méthode marchera toujours, et dans tous les cas (table vide, table dont on supprime des enregistrements à la fin...)
- Si tu es sûr de rester en Mysql, je pense que l'utilisation de auto_increment est plus rapide, car elle est lié à une table d'index, mais la notion de rapidité a un peu disparu depuis que nous avons des bécanes rapides et puissantes, donc le traitement d'une méthode ou d'un autre ne se verra pas à l'oeil nu, ou du moins elle se compterait en ms, donc mon conseil, fais celle qui t'inspire le plus, du moment que ça marche à 100%
Bye.
Marsh Posté le 06-10-2002 à 15:35:16
Je pencherais sans hésitation pour la méthode de l'autoincrement.
Non seulement parce que contrairement à ce que pense sweedy c'est quand même pas mal supporté (même DB2 c'est pour dire), et que surtout, dans MySQL t'as aucune contraintes, donc tu peux bousiller un élément dans cette table alors qu'un autre élément dans une autre table le référence, donc si tu le recrées avec le même ID plus tard, ca va conduire à un merdier pas possible.
Ou alors tu fais une table dans laquelle tu stockes le dernier ID que tu as généré (comme on faisait en natstar il me semble), mais franchement autant utiliser l'auto_increment et modifier ton code en conséquence si tu dois passer à un autre SGBD, t'auras de doute facon autre chose à modifier
Marsh Posté le 06-10-2002 à 16:44:40
slvn a écrit a écrit : j'ai decortiqué un peu phpMyAdmin : il apparait que ce que l'on cherche a faire est tout simple (encore faut il le connaire ) la requete a effectuer est : " SHOW TABLE STATUS LIKE 'ma_table' " la ligne renvoyé contient un champs qui s'appelle "Auto_increment", et qui est le prochain index crée! |
Yes!
Merci, j'avais la flemme d'aller fouiller là-dedans?
Marsh Posté le 05-10-2002 à 15:02:53
Je m'explique:
dans une bdd, j'ai un champ id en auto_increment...
Je voudrais avoir la prochaine valeur de ce champ.
Alors j'ai fait un max(id) as id que j'incrémente de 1, ce qui me donne la prochaine valeur.
Mais le problème est que lorsque j'ai déjà enregistré, disons 24 valeurs, et que je les efface toutes, la prochaine valeur de id sera 25... Mais avec le max(id), ben j'aurai 1, car le max(id) me donnera 0 comme valeur.
Comment je peux faire alors??