MySQL : trouver le bon ID

En train de développer un extranet avec une gestion assez complexe des entrées en base de données, je me suis retrouvé devant une question « existentielle » : comment connaître la valeur du prochain ID qui sera créé dans ma table ?

Ma première idée était de prendre le plus grand ID de la table et de lui ajouter 1 :

SELECT MAX(id)+1 AS next_id FROM 'my_table';

Oui, mais… ce n’est pas nécessairement le prochain ID qui sera attribué à ma prochaine insertion !

Exemple : si des rangs ont été supprimés entre temps, le prochain ID pourrait être 6534 et non pas 6490 !

Retour à la case départ ! Après de multiples recherches, je n’ai trouvé aucune fonction spécifique à MySQL qui puisse me donner cette information, jusqu’à ce que je trouve l’article de Jamie Doris, confronté au même problème que moi.

La solution vient donc de l’utilisation de la fonction SHOW TABLE STATUS LIKE… qui retourne une série d’informations dont la valeur d’une prochain incrément !

Quelques lignes de PHP plus loin, nous avons la valeur tant recherchée :

$tableName = "my_table";
$tableInfos = mysql_fetch_assoc(mysql_query("SHOW TABLE STATUS LIKE '$tableName'"));
echo $nextId = $tableInfos['Auto_increment'];

Pour ceux qui, comme moi, utilisent la classe Pear::DB, remplacez la ligne N°2 par :

$tableInfos = $db->getRow("SHOW TABLE STATUS LIKE '$tableName'");

Et voilà…

Note : j’en profite pour pointer vers un excellent tutorial sur Pear::DB.

4 commentaires

  1. Sekaijin   •  

    Salut cette solution est déjà un pas en avant. mais elle n’est pas suffisante par rapport à une vrai gestion de sequences.

    dans un sequence duex appel à NextVal donne toujours deux valeur différente.
    Avec cette solution on a bien la prochaine valeur de l’ID qui sera inséré mais ce n’est pas obligatoirement celle que le processus qui fait cet appel poura inssérer

    suposons que nous ayons deux utilisateur
    le premier cherche le nexval il obtient 10001
    le deuxième fait de même il obtient 10001
    le premier fait sont insert => Ok
    si le deuxième fait sont insert sans l’ID il inserèe le 10002 et non le 10001 comme il le supposait
    s’il fait un insert en précisant 10001 il obtient un Duplicate key

    Je n’ai toujours pas trouvé de solution à ce problème de MySQL

    laisser MySQL décider de l’ID au moment de l’insert implique d’être sur qu’un même insert de nesra pas rejouer

    déterminer l’id avant de proposer le rempissage des champs garantit qu’il ne poura y avoir de rejeux.

    avec oracle postgres sybase etc. il suffit de récupérer la valeur de la sequence avant de présenter le formulaire.

    Avec MySQL je n’ai pas trouvé. soit je laisse faire et j’ai des enregistrement en double car je ne peux garantir qu’il n’y aura pas de rejeux
    Soit je prends le risque de tombre sur le cas précédent.

    Quoi qu’il en soit cette méthode pour obtenir le prochain incrément est bien pratique

    merci
    A+JYT

  2. georgeduke   •  

    Mais pourquoi vouloir connaître la valeur du prochain ID ? Pour la requête d’insertion ? Il suffit de ne pas préciser l’ID dans la requete d’insertion et MySql gérera tout très bien tout seul.

    Si ce besoin provient d’une contrainte liée à l’interface graphique de présentation des données, il convient de la repenser car ce n’est pas normal.

  3. Tournesol   •  

    Le problème ne vient pas de l’interface mais de l’ordre du process : j’ai besoin de créer des données dans une autre table avant mon insertion principale.

    Ne pouvant inverser l’ordre des insertions j’ai cherché un moyen de « prédire » le prochain ID afin d’éviter un système « INSERT, INSERT, UPDATE » inutile.

  4. georgeduke   •  

    D’accord je comprend mieux ton problème qui a mon avis n’a pas de solution miracle… Php mériterait d’avoir l’équivalent du « DataSet » d’asp.net qui est la représentation d’une ou plusieurs tables à un moment donné. Représentation dans laquelle on peut ajouter de nouvelles lignes à certaines tables et en cas relation de clef etrangère, le tout est géré automatiquement.
    Mais peut être que les dev de PHP intègreront ces possibilités dans la prochaine version…

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>